2013-10-29 19 views
14

Tüm uygulamalarda android.view.Window s veya dekor görünümlerini programlı olarak sıralamak mümkün mü? Örneğin, her ikisi de ana Etkinlik penceresinden ayrı olarak yeni bir 'da açılacaktır. Onları Dialog.getWindow() aracılığıyla bulabilirim, ancak bunu, aktivite menüsü açılır penceresi gibi yerleşik bileşenlerle nasıl yapacağımı bilmiyorum.Belirli bir uygulama içinde tüm Windows programlı olarak yerleştirmenin bir yolu var mı?

Application, Context veya WindowManager veya başka bir şeyden, uygulamamla ilişkilendirilmiş Windows'u numaralandırmak için herhangi bir yol var mı?

Uygulamamın tüm pencerelerini adb dumpsys window ile görebiliyorum, ancak uygulamada root gerektirmeden bunu yapmanın bir yolunu arıyorum.

+0

Aktivite menüsü açılır penceresinin Penceresi, Etkinlik ile aynı olur, Activity.getWindow() işlevi sizin için işe yaramaz mı? – kassim

+0

Maalesef, hayır. Android FingerPaint örneğini (4.3'te) çalıştırıyorum ve üç nokta menü düğmesine dokunduktan sonra, pencerede açılır pencerenin kendi penceresinde olduğunu görebiliyorum. Ayrıca "ADB kabuk dumpsys pencere belirteçleri" çalıştırmak ve boya uygulaması gerçekten bağlantılı iki pencere sahip olduğunu görebilir: allAppWindows = [Pencere {418f9ce8 u0 com.example.paintsample/com.example.paintsample.PaintSample} , Pencere {41a06d08 u0 PopupWindow: 41ac65a0}] İletişim Kutuları ile aynı. –

+0

Sadece merak ediyorum, neden bu bilgiye ihtiyacın var, yoksa daha sonra, onunla ne yapacaksın? – Josh

cevap

15

Bunu @hidden WindowManagerGlobal yansımasıyla yapmanın bir yolunu buldum. En azından şu ana kadar bunun android-18 için çalıştığını biliyorum.

private void logRootViews() { 
    try { 
     Class wmgClass = Class.forName("android.view.WindowManagerGlobal");       
     Object wmgInstnace = wmgClass.getMethod("getInstance").invoke(null, (Object[])null); 

     Method getViewRootNames = wmgClass.getMethod("getViewRootNames"); 
     Method getRootView = wmgClass.getMethod("getRootView", String.class); 
     String[] rootViewNames = (String[])getViewRootNames.invoke(wmgInstnace, (Object[])null); 

     for(String viewName : rootViewNames) { 
      View rootView = (View)getRootView.invoke(wmgInstnace, viewName); 
      Log.i(TAG, "Found root view: " + viewName + ": " + rootView); 
     } 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
} 

Çıktı:

Bulunan kök görünümü: com.example.paintsample/com.example.paintsample.PaintSample/[email protected]: com.android.internal.policy .impl.PhoneWindow $ DecorView {41dcc278 ....... R .... 0,0-768,1184 VE}

Bulunan kök görünümü: PopupWindow: 42887380/[email protected] : android.widget.PopupWindow $ Popu pViewContainer {42891450 VE .... ........ 0,0-424,618}

Bounty daha iyi bir yol :)

3
bulabilirsiniz herkes için yukarı tabii elinde kalacak

SDK ile birlikte gelen Hierarchyviewer aleti ağırlığının altın değerinde olduğunu gösteriyor.

+0

Öyle ama programlı olarak yapmam için bir yol arıyordum (bunu yapmak için gizli bir sınıfa dokunmam gerekse de). Sorunu daha net hale getirmek için biraz düzeltin. –

+0

Oh tamam - Cihazın kendisinde adb dumpsys kullandığınızı düşünmedim. – Pedantic

6

Bunun gerçek soruyu yanıtladığından emin değilim, ancak kabul edilen yanıtta önerildiği gibi tüm kök görünümleri almanın daha iyi bir yolu.

public static List<View> getWindowManagerViews() { 
    try { 

     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH && 
       Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) { 

      // get the list from WindowManagerImpl.mViews 
      Class wmiClass = Class.forName("android.view.WindowManagerImpl"); 
      Object wmiInstance = wmiClass.getMethod("getDefault").invoke(null); 

      return viewsFromWM(wmiClass, wmiInstance); 

     } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { 

      // get the list from WindowManagerGlobal.mViews 
      Class wmgClass = Class.forName("android.view.WindowManagerGlobal"); 
      Object wmgInstance = wmgClass.getMethod("getInstance").invoke(null); 

      return viewsFromWM(wmgClass, wmgInstance); 
     } 

    } catch (Exception e) { 
     e.printStackTrace(); 
    } 

    return new ArrayList<View>(); 
} 

private static List<View> viewsFromWM(Class wmClass, Object wmInstance) throws Exception { 

    Field viewsField = wmClass.getDeclaredField("mViews"); 
    viewsField.setAccessible(true); 
    Object views = viewsField.get(wmInstance); 

    if (views instanceof List) { 
     return (List<View>) viewsField.get(wmInstance); 
    } else if (views instanceof View[]) { 
     return Arrays.asList((View[])viewsField.get(wmInstance)); 
    } 

    return new ArrayList<View>(); 
} 
+1

Bu burada en iyi çözüm! – refaelos

0

You: orada belirtildiği gibi

, ben de bu kodu (aşağıda işaretli değil) 14 ve yukarıdaki API bütün sürümlerini desteklemektedir dışında bu sadece kullanarak yansımayı gerçekleştirmek başardınız sınıf dosyaları erişerek ve Android SDK android.jar ekleyerek yansıma kullanmadan doğrudan @hidden APIs kullanabilirsiniz. İşte nasıl: https://devmaze.wordpress.com/2011/01/18/using-com-android-internal-part-1-introduction/

Ve android için kaynak.Belirli android sürümü (19,21,22,23,24) için kavanoz burada yakaladı edilebilir: https://github.com/anggrayudi/android-hidden-api

Öyleyse gibi tüm kök görüşlerini almak için doğrudan WindowManagerGlobal sınıfını kullanabilirsiniz

private void logRootViews() { 
    WindowManagerGlobal windowManagerGlobal = WindowManagerGlobal.getInstance(); 
    String[] rootViewNames = windowManagerGlobal.getViewRootNames(); 

    for (String viewName : rootViewNames) { 
     View rootView = windowManagerGlobal.getRootView(viewName); 
     Log.i("", "Root view is: " + viewName + ": " + rootView); 
     /*do what you want with the rootView*/ 
    } 
} 

Çıktı:

Kök görünümüdür: com.android.internal.policy.impl.PhoneWindow $ DecorView {41dcc278: com.example.paintsample/com.example.paintsample.PaintSample/[email protected] VE .... R ....... 0,0-768,1184,

Kök görünümüdür: PopupWindow: 42887380/[email protected]: android.widget.PopupWindow $ PopupViewContainer {42891450 .... VE ........ 0,0-424,618}

İlgili konular