2011-07-02 38 views
3

在三星手機上調試我的應用程序,出現奇怪的結果,我沒有物理訪問權限。我想問一個用戶運行一個儀器化的應用程序來幫助調試。我的應用得到了一個view,它有一個未知的(對我來說,-)層次結構(ViewGroups等)。有沒有辦法「走」View並打印出一個字符串/ ddmsView(etc等ViewGroups等)中的所有組件?打印設備上的視圖層次結構

這將類似於HierarchyViewer工具 - 如果我有adb級別訪問設備。

更新:我想我可以使用的方法

void dumpViewHierarchyWithProperties(Context context, ViewGroup group, BufferedWriter out, int level) 

ViewDebug.java Android操作系統源...

任何人有一個更好的主意嗎?

謝謝!

回答

25

這裏的效用函數我只是爲這個目的而作出:我創建了與人類可讀的視圖ID漂亮的印刷方式返回層次實用方法

public static void printViewHierarchy(ViewGroup vg, String prefix) { 
    for (int i = 0; i < vg.getChildCount(); i++) { 
     View v = vg.getChildAt(i); 
     String desc = prefix + " | " + "[" + i + "/" + (vg.getChildCount()-1) + "] "+ v.getClass().getSimpleName() + " " + v.getId(); 
     Log.v("x", desc); 

     if (v instanceof ViewGroup) { 
      printViewHierarchy((ViewGroup)v, desc); 
     } 
    } 
} 
+0

我會給+2 ups只在var名稱中使用$,我認爲這是不可能的,從來沒有嘗試過。 –

+0

我喜歡這個答案,但我會更好地使用以下內容,以便您可以打印該ID(如果可用): 'String desc = $ prefix +「|」+「[」+ i +「 /「+($ vg.getChildCount() - 1)+」]「+ v.getClass()。getSimpleName(); String id = null; try { id = v.getResources()。getResourceName(v.getId()); desc + =「」+(id == null?v.getId():id);}} catch(Exception e){ // no-op(no id found) } ' – Jun

+2

@Marcos:Java不是PHP ... –

0

這些觀點不是我的,他們是從其他應用程序來,所以我不能碰與之相關的代碼(我是從一個遠程視窗膨脹它們)

如果您收到一個RemoteViews,並且您將它應用於活動中的某些內容,則可以直接訪問得到的Views,與您自己從XML中擴充它們的情況沒有區別。給定根源View,這只是一個步行孩子的問題(可能是深度優先,但那是你的呼叫)並記錄你想要的任何信息。

+0

這實際上就是我所做的。我正在尋找的是一個類或庫,它提供了「預罐裝」功能。我利用ViewDebug的Android源代碼中的一些代碼,基本上做了你在這裏調用的內容。 – Yossi

7

。下面是輸出的一個例子:

[LinearLayout] no_id 
    [CardView] com.example:id/card_view 
    [RelativeLayout] no_id 
     [LinearLayout] com.example:id/image_container 
     [AppCompatImageView] com.example:id/incident_icon 
     [CustomTextView] com.example:id/road_number 
     [RelativeLayout] no_id 
     [CustomTextView] com.example:id/distance_to_user 
     [CustomTextView] com.example:id/obstruction_title 
     [CustomTextView] com.example:id/road_direction 
     [CustomTextView] com.example:id/obstruction_description 
     [AppCompatImageView] com.example:id/security_related 

這裏是實用方法:

public static String getViewHierarchy(@NonNull View v) { 
    StringBuilder desc = new StringBuilder(); 
    getViewHierarchy(v, desc, 0); 
    return desc.toString(); 
} 

private static void getViewHierarchy(View v, StringBuilder desc, int margin) { 
    desc.append(getViewMessage(v, margin)); 
    if (v instanceof ViewGroup) { 
     margin++; 
     ViewGroup vg = (ViewGroup) v; 
     for (int i = 0; i < vg.getChildCount(); i++) { 
      getViewHierarchy(vg.getChildAt(i), desc, margin); 
     } 
    } 
} 

private static String getViewMessage(View v, int marginOffset) { 
    String repeated = new String(new char[marginOffset]).replace("\0", " "); 
    try { 
     String resourceId = v.getResources() != null ? (v.getId() > 0 ? v.getResources().getResourceName(v.getId()) : "no_id") : "no_resources"; 
     return repeated + "[" + v.getClass().getSimpleName() + "] " + resourceId + "\n"; 
    } catch (Resources.NotFoundException e) { 
     return repeated + "[" + v.getClass().getSimpleName() + "] name_not_found\n"; 
    } 
} 

提示:我們使用這種方法來查看層次結構添加到一些崩潰報告。 在某些情況下,它確實有幫助