关于对Instrumentation的个人理解

作者: Android架构 | 来源:发表于2019-06-18 14:15 被阅读16次

    前言

    一般的应用不太会用到instrumentation,所以网上对其介绍也比较少。

    但因其强大的跟踪application及activity生命周期的功能,用于android 应用测试框架中,被做为基类使用。

    instrumentation的官方文档:http://developer.android.com/intl/zh-cn/reference/android/app/Instrumentation.html

    查看其提供的方法,比如:callActivityOnCreate,callApplicationOnCreate,newActivity,callActivityOnNewIntent 等基本上在application和activity的所有生命周期调用中,都会先调用instrumentation的相应方法。并且针对应用内的所有activity都生效。为程序员提供了一个强大的能力,有更多的可能性进入android app框架执行流程。

    对于每一个android app来说,它的总入口都是ActivityThread::main. 每一个应用的进程都有一个ActivityThread对象,而每一个ActivityThread对象都有一个Instrumentation mInstrumentation;成员变量。mInstrumentation的初始化在ActivityThread::handleBindApplication函数中:

    if (data.instrumentationName !=null) {
    ...
        java.lang.ClassLoader cl = instrContext.getClassLoader();
        mInstrumentation = (Instrumentation)
                        cl.loadClass(data.instrumentationName.getClassName()).newInstance();
    ...
    } else {
        mInstrumentation =newInstrumentation();
    }
    
    

    自定义的instrumentation只能通过调用Context.startInstrementation或者命令行am instrument启动,这个过程会将目标进程杀死再重启(声明instrumention的应用与目标应用签名必需一致)。如果应用不是通过上述方式启动而是正常情况下(通过launcher或者startActivity)启动,会默认new 一个系统的Instrumentation.

    如果某应用要自定义instrumentation且用于跟踪本应用内的application及activity生命周期,通过继承实现Instrumentation并反射修改ActivityThread.mInstrumentation的方法可以做到。以下是具体做法:

    1、自定义Instrumentation
    class MyInstrumentation extends Instrumentation {
      ...
    };
    
    
    2、反射调用修改ActivityThread.mInstrumentation
    MyInstrumentation ins = new MyInstrumentation();
    
    Class cls = Class.forName("android.app.ActivityThread"); // ActivityThread被隐藏了,所以通过这种方式获得class对象
    
    Method mthd = cls.getDeclaredMethod("currentActivityThread", (Class[]) null); // 获取当前ActivityThread对象引用
    
    Object currentAT = mthd.invoke(null, (Object[]) null);
    
    Field mInstrumentation = currentAT.getClass().getDeclaredField("mInstrumentation");
    
    mInstrumentation.setAccessible(true);//设置private变量为可读取
    
    mInstrumentation.set(currentAT, ins); // 修改ActivityThread.mInstrumentation值
    
    

    至此即可通过MyInstrumentation来跟踪应用内application及activity的生命周期。

    自己是从事了七年开发的Android工程师,不少人私下问我,2019年Android进阶该怎么学,方法有没有?

    没错,年初我花了一个多月的时间整理出来的学习资料,希望能帮助那些想进阶提升Android开发,却又不知道怎么进阶学习的朋友。【包括高级UI、性能优化、架构师课程、NDK、Kotlin、混合式开发(ReactNative+Weex)、Flutter等架构技术资料】,希望能帮助到您面试前的复习且找到一个好的工作,也节省大家在网上搜索资料的时间来学习。

    资料获取方式:加入Android架构交流QQ群聊:513088520 ,进群即领取资料!!!

    点击链接加入群聊【Android移动架构总群】:加入群聊

    资料大全

    相关文章

      网友评论

        本文标题:关于对Instrumentation的个人理解

        本文链接:https://www.haomeiwen.com/subject/tvvkfctx.html