APP启动时Activity的进程间通讯Binder机制

来源:互联网 发布:2016非农数据走势图 编辑:程序博客网 时间:2024/05/11 17:28

一 . 理论基础

在Android中,由于Binder通信机制的存在,进程迁移使用的非常非常频繁,Android四大组件都可以进行进程间数据通讯。

对于Binder Service端:

 (1) 定义AIDL文件来公开服务的接口(比如  scheduleLauncherActivity,bindApplication,shceduleReceiver或者mic,打开camera,点灯等等) (2)编译AIDL生成对应的接口interface的java文件 (3)实现自定义Android系统 Service的java类,该类要求继承(2)步中的interface的stub子类(eg:public static abstract class Stub extends android.os.Binder implements android.os.ILedService)    这样该自定义服务变具备的 1. 硬件操控功能(实现了interface) 2.进程间通讯功能 (因为继承了Binder) (4).将该service添加到SystemServer ( eg:ServiceManager.addService("lcled",  new  LedService());)

对于Binder Client端

  (1)通过ServiceManager.getService("lcled")获取远程服务的Binder,也即是远程Stub。(如Binder Service端(3)所示这个Stub需要实现功能接口Ixxx,又要继承Binder类)     (注意系统中首先要有ILedService      1.  可以利用mmm命令自编androdid系统生成相应的class.jar,然后以jar的形式导入android studio并在Project Structure设置Dependency       然后在APP中import android.os.ILedService;      2 . 可以仿造应用层,拷贝Service第一步aidl文件来生成相应的java接口类 )  (2)利用ILedService.Stub.asInterface(第(1)步的Binder) ;转成了对应硬件功能接口的代理Proxy。因为该Proxy在aidl生成java接口类时,作为Stub的内部类已经实现了外部       父类接口,那么便可以利用Proxy拥有的成员方法访问远程服务,这样实现了IPC通讯

总结:
AIDL只是一个类似Webservie的功能清单接口,继承了它的类便可以拥有对应的服务功能。

      真正实现夸进程通讯的是Binder,也就是该AIDL内部的Stub类。(类似具体的SOAP了)服务的主调方获取该Stub,然后利用该Stub内部的代理Proxy调用功能接口。

二. 开始分析Activity的启动过程

  主要涉及两个方向的IPC通讯,分别对应不同的功能的Binder实现类

当APP代码中调用startActivity时,
startActivitForResult
mInstrumentation.execStartActivity(this,mainThread.getApplicationThread(),x,x,x,x,x)
{
IApplicationThread whoThread =( IApplicationThread ) mainThread.getApplicationThread()
//这里的 IApplicationThread 就是一个AIDL生成的功能接口类

                          ActivityMannagerNative.getDefault().startActivity(whoThread,x,x,x,x,x......)                  }

*Note** :至此出现了第一个IPC通讯,ActivityMannagerNative( ActivityManagerNative extends Binder implements IActivityManager因此这个 ActivityManagerNative对应是AIDL中的Stub)

APP端作为Binder的Client
在 ActivityMannagerNative.java的ActivityMannagerNative.getDefault()方法中

IBinder b = ServiceManager.getService("activity"); (这里获取的是ActivityMannagerService这个Binder)        if (false) {            Log.v("ActivityManager", "default service binder = " + b);        }        IActivityManager am = asInterface(b);        if (false) {            Log.v("ActivityManager", "default service = " + am);        }        return am;我猜测这里返回了ActivityMannagerProxy,注意这个ActivityMannagerProxy肯定是ActivityMannagerNative的内部类,并且肯定实现了IActivityManager,看代码果不其然那么继续可以猜测ActivityMannagerService肯定继承了ActivityMannagerNative,看源码可以得到证实。(这里的ActivityMannagerService是具体实现IActivityManager接口功能java类,相当于继承AIDL中内部stub的Ledservice这些具体功能类,见理论基础第(3)步)这样通过IPC,代码从APP的进程切换到AMS进程system_process继续执行

现在到AMS的startActivity

startActivity(IApplicationThread caller,x,x,x.....)                 startActivityAsUser(IApplicationThread caller,x,x,x.....)                  mStackSupervisor.startActivityMayWait(IApplicationThread caller,x,x,x.....)                    startActivityLocked                       startActivityUncheckedLocked                          resumeTopActivityLocked                              resumeTopActivityLockedInnerLocked                                startSpecificActivityLocked                                  realStartActivityLocked                                    {                                        app.thread.scheduleLaunchActivity(new Intent(r.intent),x,x,x.....)                                     }

Note: 这里的app.thread类型为 IApplicationThread,分析源码发现其继承了IInterface接口,因此也是一个Binder, 而其实app.thread就是ActivityThread.ApplicationThread,这个Binder是ActivityThread与AMS进程通信的时候传过去的参数,也就是上面IApplicationThread whoThread
至此,第二个Binder出现了,只不过这次是以client binder出现,而APP的主线程ActivityThread的内部类ApplicationThread才是这里的stub,那么可以猜测ApplicationThread一定继承了Binder并且是实现了IApplicationThread,观察源码在ActivtyThread中有内部类 ApplicationThread extends ApplicationThreadNative而
public abstract class ApplicationThreadNative extends Binder
implements IApplicationThread { ,//真是果不其然

总结,app调用了startActivity后,先从ActivityThread主线程通过第一个Binder(ActivityMannagerService)切入系统system_process调用AMS功能。而后又通过第一次RPC远程调用传过去的Binder(ApplicationThread)切换回了APP的进程,继续执行。而真正启动Activiy的功能代码肯定还是在主线程ActivitThread的内部类ApplicationThread中。

最终得到应用APP启动的一个过程:

系统得到启动某个APP的命令后,主动去启动Action为android.intent.action.MAIN. category ="android.intent.category.LAUNCHER"的Activity接着通过Binder ActivityMannagerService 将该请求发给在System_process执行一些处理后,通过 ApplicationThread 这个Binder返回APP所在进程,然后在进程的主线程ActivityThread中通过给主线程的Handle发消息调用其handleLanucherActivity方法,

这里会
一.
(1)获取新Activity组件信息。
(2)利用类加载器ClassLoader创建新Activity
(3)通过LoadedApl的makeApplicaotion方法创建Application(已经存在则直接返回)
(4)创建contextimpl并attach到新的activity
(5)将activity与window关联
(6)mInstrumentation.callActivityOnCreate方法调用activity的onCreate方法
二.
handleResumeActivity,最终调用activity的onResume方法

1 0