2013-10-29 9 views
14

क्या android.view.Window एस, या किसी एप्लिकेशन के भीतर सजावट के दृश्यों को प्रोग्रामेटिक रूप से समझा जाना संभव है?क्या किसी दिए गए एप्लिकेशन के भीतर प्रोग्रामेटिक रूप से सभी विंडोज़ का पता लगाने का कोई तरीका है?

Dialogs उदाहरण के लिए मुख्य गतिविधि विंडो से अलग, एक नया Window में खुल जाएगा। मैं उन्हें Dialog.getWindow() के माध्यम से ढूंढ सकता हूं लेकिन मुझे यकीन नहीं है कि मैं गतिविधि मेनू पॉपअप जैसे अंतर्निहित घटकों के साथ ऐसा कैसे करूं।

क्या कोई तरीका है, Application, Context, या WindowManager, या कुछ और, मेरे ऐप से जुड़े विंडोज को गिनने के लिए?

मैं अपने सभी एप्लिकेशन की विंडोज़ adb dumpsys window के साथ देख सकता हूं, लेकिन मैं रूट के बिना अपने आवेदन के भीतर ऐसा करने का एक तरीका ढूंढ रहा हूं।

+0

गतिविधि मेनू पॉपअप के लिए विंडो गतिविधि की तरह ही होगी, गतिविधि.getWindow() आपके लिए काम नहीं करेगी? – kassim

+0

दुर्भाग्य से, नहीं। मैं एंड्रॉइड फिंगरपेंट नमूना चला रहा हूं (4.3 पर) और जब मैं तीन डॉट मेनू बटन टैप करता हूं, और मैं मॉनीटर में देख सकता हूं कि पॉपअप अपनी खिड़की में है। मैं भी "विंडो टोकन adb shell dumpsys" चला सकते हैं और देखो रंग एप्लिकेशन वास्तव में दो खिड़कियां इसके साथ जुड़े है: allAppWindows = [विंडो {418f9ce8 u0 com.example.paintsample/com.example.paintsample.PaintSample} , विंडो {41a06d08 u0 पॉपअपविंडो: 41ac65a0}] संवाद के साथ ही। –

+0

बस उत्सुक, आपको इस जानकारी की आवश्यकता क्यों होगी, या इसके बजाय, आप इसे प्राप्त करने के बाद इसके साथ क्या करने जा रहे हैं? – Josh

उत्तर

15

मुझे @hidden WindowManagerGlobal पर प्रतिबिंब के माध्यम से ऐसा करने का एक तरीका मिला है। कम से कम अब तक मैं एंड्रॉइड -18 के लिए यह काम जानता हूं।

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(); 
    } 
} 

आउटपुट:

मिले जड़ दृश्य: com.example.paintsample/com.example.paintsample.PaintSample/[email protected]: com.android.internal.policy .impl.PhoneWindow $ DecorView {41dcc278 ....... VE .... आर 0,0-768,1184}

मिले जड़ दृश्य: PopupWindow: 42887380/[email protected] : android.widget.PopupWindow $ Popu pViewContainer {42891450 VE .... ........ 0,0-424,618}

बाउंटी अभी भी किसी को जो एक बेहतर तरीका :)

3
पा सकते हैं के लिए निश्चित रूप से पकड़े जाने के लिए है

Hierarchyviewer उपकरण जो एसडीके के साथ आता है वह सोने में अपना वजन लायक है।

+0

यह है, लेकिन मैं इसे प्रोग्रामेटिक रूप से करने का एक तरीका ढूंढ रहा था (जो मेरे पास है, हालांकि मुझे इसे करने के लिए एक छिपे हुए वर्ग को छूना है)। उस स्पष्ट को ठीक करने के लिए प्रश्न को ठीक करेगा। –

+0

ओह ठीक है - मैंने यह नहीं सोचा था कि आप डिवाइस पर adb dumpsys का उपयोग कर रहे थे। – Pedantic

6

मुझे पूरा यकीन नहीं है कि यह वास्तविक प्रश्न का उत्तर देता है, लेकिन यह स्वीकार किए गए उत्तर में सुझाए गए सभी मूल विचारों का एक बेहतर तरीका है।

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

यह सबसे अच्छा समाधान है !! – refaelos

0

आप:

वहाँ उल्लेख किया है, मैं भी छोड़कर इस कोड एपीआई 14 और इसके बाद के संस्करण (मैं नीचे की जाँच नहीं की है) से सभी संस्करणों का समर्थन करता है इस प्रतिबिंब केवल का उपयोग कर पूरा करने के लिए, प्रबंधित किया है वर्ग फ़ाइलों तक पहुंचकर प्रतिबिंब का उपयोग किए बिना और फिर एंड्रॉइड एसडीके में अपने android.jar में जोड़कर @ hidden एपीआई का उपयोग कर सकते हैं। यहां बताया गया है कि: https://devmaze.wordpress.com/2011/01/18/using-com-android-internal-part-1-introduction/

और एंड्रॉइड के लिए स्रोत।विशिष्ट एंड्रॉयड संस्करण (19,21,22,23,24) के लिए जार यहाँ पकड़ा जा सकता है: https://github.com/anggrayudi/android-hidden-api

तो फिर आप WindowManagerGlobal वर्ग सीधे उपयोग कर सकते हैं की तरह सभी जड़ प्राप्त करने हेतु,

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*/ 
    } 
} 

आउटपुट:

रूट दृश्य है: com.example.paintsample/com.example.paintsample.PaintSample/[email protected]: com.android.internal.policy.impl.PhoneWindow $ DecorView {41dcc278 वीई .... आर ....... 0,0-768,1184}

रूट दृश्य है: PopupWindow: 42887380/[email protected]: android.widget.PopupWindow $ PopupViewContainer {42,891,450 VE .... ........ 0,0-424,618}

संबंधित मुद्दे

 संबंधित मुद्दे