Search code examples
androidui-automationandroid-uiautomatorandroid-instrumentation

how to use Instrumentation under the uiautomator project?


I'm working on a uiautomator project recently and then the UiObject.getFromParent turn out a wrong element to me and I look into the source code of uiautomator and found out the answer is because by the UiSelector I used.

I found that the uiautomator is using the Instrumentation to get the UI element stuff just like :

getInstrumentation().getUiAutomation().getRootInActiveWindow();

I just want to get a AccessibilityNodeInfo node just like what uiautomator do but the uiautomator didn't exposed this.

I’m trying this way by a new class extends InstrumentationTestCase,by the getInstrumentation() always return a null to me.

i found an answer on android instrumentation test case - getinstrumentation() returning null that needs injectInstrumentation(InstrumentationRegistry.getInstrumentation()); and told InstrumentationRegistry is from the official Android testing-support-lib:0.1

I have download the Android Support Repository and import the testing-support-lib-0.1-source.jar into my project but I still can't see InstrumentationRegistry.

Anyone have any idea about my cast?


Solution

  • Frist tried:

    i have noticed that the point of this question is the uiautomator didn't expose the api i want,and when i look into the source and found the UiDevice.dumpWindowHierarchy that has these code:

    AccessibilityNodeInfo root =getAutomatorBridge().getQueryController().getAccessibilityRootNode();
     the getAutomatorBridge was implemented by UiDevice:
       UiAutomatorBridge getAutomatorBridge() {
            if (mUiAutomationBridge == null) {
                throw new RuntimeException("UiDevice not initialized");
            }
            return mUiAutomationBridge;
        }
    

    the point is there is no modifier on it,so what i have done is modified it's modifier to public ,modified the byte code of

    /system/framework/uiautomator.jar

    and the other one in sdk(sorry i don't,ya it worked!i can use it like this.

    AccessibilityNodeInfo root =getUidevice().getAutomatorBridge().getQueryController().getAccessibilityRootNode();
    

    but there is a compatibility issue isn't it?

    Second tried:

    Let's think about the default modifier of java,we can access it under the same package,so why don't we just implement a class has the same Package name ?then we can call it without any unnomal patch. that's what i have done and it really works well:

    package com.android.uiautomator.core;
    
    import android.view.Display;
    import android.view.accessibility.AccessibilityNodeInfo;
    
    public class AutomationUltilites
    {
        public AutomationUltilites()
        {
        }
        public static AccessibilityNodeInfo  getRootNode()
        {
            return UiDevice.getInstance().getAutomatorBridge().getRootInActiveWindow();
        }
        public static Display getDisplay()
        {
            return UiDevice.getInstance().getAutomatorBridge().getDefaultDisplay();
        }
    }
    

    Hope it helps.