淘宝做网站为什么那么便宜,网站设计公司产品介绍,重庆平台网站建设工作,加强网站建设的请示前言 学习UiDevice对象#xff0c;就需要看它的构造方法#xff0c;构造方法中有UiDevice对象持有一些对象#xff0c;每个对象都是我们分析程序的重点#xff0c;毕竟UiDevice对象的功能#xff0c;依赖这些组合的对象 备注#xff1a;当前对象持有的对象#xff0c;初…前言 学习UiDevice对象就需要看它的构造方法构造方法中有UiDevice对象持有一些对象每个对象都是我们分析程序的重点毕竟UiDevice对象的功能依赖这些组合的对象 备注当前对象持有的对象初始化的位置一般在实例变量创建时或者构造方法中以下是UiDevice构造方法中正在做初始化对象的代码 UiDevice(Instrumentation instrumentation) {mInstrumentation instrumentation;mQueryController new QueryController(instrumentation);mInteractionController new InteractionController(instrumentation);// Enable multi-window support for API level 21 and upif (UiDevice.API_LEVEL_ACTUAL Build.VERSION_CODES.LOLLIPOP) {// Subscribe to window informationAccessibilityServiceInfo info getUiAutomation().getServiceInfo();info.flags | AccessibilityServiceInfo.FLAG_RETRIEVE_INTERACTIVE_WINDOWS;getUiAutomation().setServiceInfo(info);}
} UiAutomation对象很重要 我们看到getUiAutomation方法在UiDevice构造方法中的调用 AccessibilityServiceInfo info getUiAutomation().getServiceInfo(); info.flags | AccessibilityServiceInfo.FLAG_RETRIEVE_INTERACTIVE_WINDOWS; getUiAutomation().setServiceInfo(info); getUiAutomatrion方法分析
位于UiDevice类中的getUiAutomation方法返回值是UiAutomation对象 UiAutomation getUiAutomation() {return getUiAutomation(getInstrumentation());}
1、先调用一个getInstrumentation方法
该方法返回的Instrumentation对象会再被传入到接受一个参数的getUiAutomation重载方法中
2、再次调用重载的getUiAutomation方法
3、此重载方法的返回值将作为当前getUiAutomation方法的返回值 我们先学习一下Instrumentation对象是如何获取到的即getInstrumentation()的调用 getInstrumentation方法分析 位于UiDevice中的getInstrumentation方法返回值为Instrumentation对象 Instrumentation getInstrumentation() {return mInstrumentation;} 通过该方法就可以得到UiDevice对象持有的Instrumentation对象mInstrumentation方法内部通过return语句返回mInstrumentation说明Instrumentation对象已经初始化结束这里只是返回 Instrumentation对象在哪初始化的 通过代码得知是创建UiDevice的时候传入的一个Instrumentation对象 创建UiDevice对象 public static final UiDevice mDevice UiDevice.getInstance(getInstrumentation()); 这时候传入的其实是InstrumentationRegistry下的静态方法getInstrumentation返回的Instrumenation对象。 public static Instrumentation getInstrumentation() {Instrumentation instance instrumentationRef.get();if (null instance) {throw new IllegalStateException(No instrumentation registered! Must run under a registering instrumentation.);}return instance;
} 一个原子对象负责持有Instrumentation对象 找到了原子对象赋值的地方
我们需要找到registerInstance这个静态方法在哪里被调用即可 在MonitoringInstrumentation对象中的oncreate方法中调用了 MonitoringInstrumentation对象从名字上果然是Instrumentation的子类它是具体的对象代码追踪到这里只要再找到这个oncreate方法在哪里调用即可! 很快找到了追踪了整个Unit框架了都要 AndroidJUnitRunner是MonitoringInstrumentation的子类看来AndroidJUnitRunner也是个Instrumentation AndroidUnitRunner作为入口类
我们是在am instrument 指定的该类这一切明白了这个用到的Instrumentation对象其实就是AndroidUnitRunner对象 $ADB shell am instrument -w -e class com.xxx.camauto.Common#unlockScreen com.xiaomi.camauto.test/androidx.test.runner.AndroidJUnitRunner重载的静态方法getUiAutomationInstrumentation方法分析
位于UiDevice类中的静态方法getUiAutomation它接受一个Instrumentation对象最后会返回一个UiAutomation对象 static UiAutomation getUiAutomation(final Instrumentation instrumentation) {int flags Configurator.getInstance().getUiAutomationFlags();if (UiDevice.API_LEVEL_ACTUAL Build.VERSION_CODES.M) {return instrumentation.getUiAutomation(flags);} else {// Custom flags not supported prior to N.if (flags ! Configurator.DEFAULT_UIAUTOMATION_FLAGS) {Log.w(LOG_TAG, UiAutomation flags not supported prior to N - ignoring.);}return instrumentation.getUiAutomation();}}
1、获取配置对象中的UiAutomation的标志位
首先通过Configurator对象的getUiAutomationFlags方法得到一个int值该值的初始值是0然后再将该int值赋值给局部变量flags存储flags存储的是关于UiAutomatrion对象的标志位说明Configurator对象存储着UI Automator测试框架用到的各种配置信息此时局部变量flags存储的值正是从Configurator对象中获得后面单独文章总结
2、系统版本大于API 23获取UiAutomation对象的方式
接着做API版本判断UiDevice类持有的API_LEVEL_ACTUAL代表API版本根据API版本执行不同的逻辑
当API版本大于MAPI23时使用的传入的Instrumentation对象的接受一个整型参数的getUiAutomation方法此时会将局部变量flags传入进去getUiAutomationint方法返回的是一个UiAutomation对象看这个flags决定了获取对象的不同
3、系统版本小于等于API 23获取UiAutomation对象的方式
当API版本小于等于MAPI23时使用的是传入的Instrumentation对象的无参数的getUiAutomation方法该方法也会返回一个UiAutomation对象
说明最终getUiAutomation方法中依赖Instrumentaion对象获取到的UiAutomation对象 找到具体的UiAutomation对象 从前面的步骤得知这个Instumentation对象其实是AndroidJUnitRunner而调用的getUiAutomation获取到的UiAutomation对象由于java是单继承我们只要沿着AndroidJunitRunner的继承树 找到getUiAutomation方法就能知道具体的UiAutomation对象在哪里创建的
1、先从AndroidJunitRunner中找getUiAutomation方法发现该类没有该方法 2、只能继续从它的父类MonitoringInstrumentation中找getUiAutomation方法这是面向对象程序的特点记住了各位结果还是没有这个方法
3、继续从它的父类ExposedInstumentationApi中查找发现还是没有 4、继续从父类Instrumentation中查找总算找到了
原来是UiAutomation对象必须创建的时候才会创建必须创建是指没创建与已经销毁
可以看到把当前App上下文的主线程Looper对象传递进去了 总结
1、追踪了一圈也知道UiAutomation对象是在哪里创建
2、面向对象程序子类找不到的方法按照继承结构继续向上找就对了。。