【Android源码-AMS】(一)Instrumentation类解析

 注:转载请注明来自Nemohttp://blog.csdn.net/nemo__


一、包名
         android.app.Instrumentation
       这里研究AMS中的Instrumentation类,当然在PMS的PackagePaser中也有同名的内部类(还有Activity, Service, Provider等),它们是PMS用于解析应用应用的Manifest文件的中间类,不在本次讨论之列。


二、概述         
        Instrument, 仪器,乐器,工具。Instrumentation, 仪器化,使用仪器。Android源码是google工程师用英文写的,所以对于每一个类的命名也许只有身处他们的语言环境下才真正理解他们所要表达的含义,经过翻译也许能帮我们稍微体会一点他们当时命名这个类的意思。
       Android文档中对Instrumentation类的描述:
       /**
         * Base class for implementing application instrumentation code.  When running
         * with instrumentation turned on, this class will be instantiated for you
         * before any of the application code, allowing you to monitor all of the
         * interaction the system has with the application.  An Instrumentation
         * implementation is described to the system through an AndroidManifest.xml's
         * <instrumentation> tag.
         */
        大意是:Instrumentation类会在应用的任何代码执行前被实列化,用来监控系统与应用的交互。可在以应用的AndroidManifest.xml中<instrumentation>标签来注册一个Instrumentation的实现。
       
        Java是面向对象的编程语言,每一个类都是一现实世界的一类对象的特征描述,所以粗略地过一下Instrumentation.java代码实现,先在大脑里对它有一个整体的印象,然后在对该类的成员变量细看一下,可以知道这个类的规模,最后浏览一遍所有的方法,就可以大致这个类可能的特征和行为。
        Instrumentation类没继承任何父类,也没实现任何接口,这样也比较好理解。
         Instrumentation另一个重要作用是提供Android组件单元测试。


三、java.lang.instrument.Instrumentation        

        利用 Java 代码,即 java.lang.instrument 做动态 Instrumentation 是 Java SE 5 的新特性,它把 Java 的 instrument 功能从本地代码中解放出来,使之可以用 Java 代码的方式解决问题。使用 Instrumentation,开发者可以构建一个独立于应用程序的代理程序(Agent),用来监测和协助运行在 JVM 上的程序,甚至能够替换和修改某些类的定义。有了这样的功能,开发者就可以实现更为灵活的运行时虚拟机监控和 Java 类操作了,这样的特性实际上提供了一种虚拟机级别支持的 AOP 实现方式,使得开发者无需对 JDK 做任何升级和改动,就可以实现某些 AOP 的功能了。

        在 Java SE 6 里面,instrumentation 包被赋予了更强大的功能:启动后的 instrument、本地代码(native code)instrument,以及动态改变 classpath 等等。这些改变,意味着 Java 具有了更强的动态控制、解释能力,它使得 Java 语言变得更加灵活多变。

        在 Java SE6 里面,最大的改变使运行时的 Instrumentation 成为可能。在 Java SE 5 中,Instrument 要求在运行前利用命令行参数或者系统参数来设置代理类,在实际的运行之中,虚拟机在初始化之时(在绝大多数的 Java 类库被载入之前),instrumentation 的设置已经启动,并在虚拟机中设置了回调函数,检测特定类的加载情况,并完成实际工作。但是在实际的很多的情况下,我们没有办法在虚拟机启动之时就为其设定代理,这样实际上限制了 instrument 的应用。而 Java SE 6 的新特性改变了这种情况,通过 Java Tool API 中的 attach 方式,我们可以很方便地在运行过程中动态地设置加载代理类,以达到 instrumentation 的目的。

        另外,对 native 的 Instrumentation 也是 Java SE 6 的一个崭新的功能,这使以前无法完成的功能 —— 对 native 接口的 instrumentation 可以在 Java SE 6 中,通过一个或者一系列的 prefix 添加而得以完成。

        最后,Java SE 6 里的 Instrumentation 也增加了动态添加 class path 的功能。所有这些新的功能,都使得 instrument 包的功能更加丰富,从而使 Java 语言本身更加强大。

        Instrumentation 的最大作用,就是类定义动态改变和操作。在 Java SE 5 及其后续版本当中,开发者可以在一个普通 Java 程序(带有 main 函数的 Java 类)运行时,通过 – javaagent参数指定一个特定的 jar 文件(包含 Instrumentation 代理)来启动 Instrumentation 的代理程序。


四、源码解析
1. Activity.java
1.1 成员mInstrumentation初始化  Activity类有一个私有Instrumentation成员mInstrumentation, 它只在Activity的attach()方法被赋值初始化。
// set by the thread after the constructor and before onCreate(Bundle savedInstanceState) is called.
private Instrumentation mInstrumentation;
......
ActivityThread】[performLaunchActivity()]
  ↓
Activity】[attach()]
  ↓
mInstrumentation = instr;
       前面分析过从一个Activity子类A通过startActivity()方法启动另一个Activity, 最后就是走到了ActivityThread的performLaunchActivity()方法,在这里通过ClassLoader找到要启动的Activity子类B,然后调用Activity子类B的attach()方法给Activity子类B赋以mInstrumentation。

1.2 startActivityForResult()  Activity有几个类似的启动另一个Activity的方法startActivityForResult()一类方法,都是通过Instrumentation的execStartActivity()方法,并返回结果:
       Instrumentation.ActivityResult ar =  mInstrumentation.execStartActivity();

Activity】[startActivity()]
  ↓
Activity】[startActivityForResult()]
  ↓
Instrumentation】[execStartActivity()]
......
        从Activity的启动流程看,这个函数执行比较早的,这里的mInstrumentation要与上面的区分开来,这里是已启动的Activity子类A中的, 它已被初始化,而后面经attach后初始化的是Activity子类B的mInstrumentation。

1.3 performStart(), performRestart(), performResume(), performStop()  Activity的这四个方法会去调用 mInstrumentation的 callActivityOnStart(), callActivityOnRestart(), callActivityOnResume(), callActivityOnStop(), 最终Activity的这四个方法会在ActivityThread对应的performXXXActivity()方法中被调用。
ActivityThread】[performLaunchActivity()]
  ↓
Activity】[performStart()]
  ↓
Instrumentation】[callActivityOnStart()]
  ↓
Activity】[onStart()]
......
        此处mInstrumentation是被启动的Activity子类B经attach后成员变量。

2. ActivityThread.java
2.1 成员mInstrumentation初始化  ActivityThread成员mInstrumentation, 它初始化的地方有三个:
        (1) attach(boolean system), 此处system为true, 表示创建的是SystemServer进程时,构造一个空的Instrumentation进行赋值, 并初始化SystemContext.
SystemServer】[main()]
  ↓
SystemServer】[run()]
  ↓
SystemServer】[createSystemContext()]
  ↓
ActivityThread】[ systemMain()]
  ↓
ActivityThread 】[ attach (true)]
......

        (2) handleBindApplication(), [data.instrumentationName != null]  组件显示调用startInstrumentation()方法才走到这里。此时会通过ClassLoader的loadClass()找到该Class, 并实例化赋值给mInstrumentation, 并通过init()进行初始化。(此处要看是否有标签<instrumentation>)
......
ActivityManagerService】[startProcessLocked()]
  ↓
Process】[start("android.app.ActivityThread", ...)]
  ↓
ActivityThread】[m ain()]
  ↓
ActivityThread 】[ attach (false)]
  ↓
ActivityManagerService 】[ attachApplication ()]
  ↓
ActivityManagerService 】[ attachApplicationLocked ()]
  ↓
ActivityThread.ApplicationThread 】[ bindApplication ()]
  ↓
ActivityThread 】[ handleBindApplication ()]
          这里再跟踪哪里给
  • 1
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值