从Activity的启动细窥BinderIPC(3)

来源:互联网 发布:大数据产业园规划 编辑:程序博客网 时间:2024/05/17 04:08

本文章我们再回来说说ActivityManagerService,类似于我们的IPC,它的基类其实就是所谓的binder,而binder又是以智能指针的形式存在IBinder中,在java语言中就是所谓的接口实现啦,当然ActivityManagerService是直接继承自ActivityManagerNative类,这个类又实现了IActivityManager接口,所以这个代理对象可以充分管理本地的activity,由于它的本质又是一个binder所以又可以起到ipc的功能,当然前面所过这个binder server是位于system server的进程。但在应用程序中ActivityManagerService一般不会直接露面,它一般指派一个ActivityManagerProxy对象替他干活,应用通过调用这个对象来获取ActivityManagerService的功能,包括提供的startActivity的方法,但这个对象不是直接构造的,需要通过ActivityManagerNative的getDefault()方法获得,下面来讨论下载Activity中关于线程的一些问题:
上次说到ActivityManagerService是继承自binder类,具有ipc的一个沾合剂的作用,app进程的进程通信基本依靠ActivityManagerService来进行实现,app进程尽情远程调用远在system server进程的ActivityManagerService(运行在一个特定线程),来进行远程函数的调用,完成进程通信,然而回过头来,ActivityManagerService总要有手段来控制住应用程序的进程,这时候就需要跟ActivityManagerService类似的一个ApplicationThreadProxy对象,这个对象的玩法类似于ActivityManagerProxy对象(又是一个替身),本质上就是一个代理,通过和继承自binder类的ApplicationThreadNative类
同时实现IApplicationThread接口来实现对binder功能的调用,ApplicationThreadProxy是system server进程中ActivityManagerService所在线程在app进程的一个代理(已经可以调用binder功能,就有成为一个进程通信的资格咯)ActivityManagerService通过调用ApplicationThreadProxy对象就相当于调用了ApplicationThreadNative类的一个子类ApplicationThread的功能(然而它的基类又是binder,binder上面还用IBinder接口进行封装),通过这层调用关系ActivityManagerService就完全充当进程通信的一个代理对象,简单来说,就是app进程通过调用ActivityManagerProxy来调用ActivityManagerService,然而反过来,ActivityManagerService通过调用自己线程的一个代理ApplicationThreadProxy对象就可控制app进程,一次app各个Activity跟远在server system进程的远程调用就完成啦。插个话,其实ActivityManagerService还是挺任劳任怨的,我们app中的一些backstack(中文就叫做回退栈吧),还有包含一个backstack的Task都是由它来进行管理的,比较幸运的是管那么一个backstack就够了。
总结下Activity的启动吧,一切的开始其实我们的launcher也就是一个startActivity()方法,上面只是从内核层开始分析,好让大家心中留个底, 上面一堆说到ActivityManagerService可以提供app的入口Activity启动,这故事明显还没结束,那么ActivityManagerService怎么启动一个Activity呢,无论是我们点击图标还是在代码中调用startActivity()方法来启动Activity,观察这个函数的实现源代码,就可发现实际里面是调用一个Instrumentation对象的execStartActivity()方法来进行启动,参数当然需要context(这个是activity的基类,就是执行的上下文,以后会详细讲解),还有当前activity运行的线程,当然是指ui主线程,后面就是一些标识身份的token啊, intent(传递的数据,这个属于activity间通信,比较简单我就不废话啦),根据上面的思路,Instrumentation的这次调用就是调用了ActivityManagerProxy对象的startActivity()方法,所以本质上还是ActivityManagerService
功能的一个调用,下面看看代码吧:
int result = ActivityManagerNative.getDefault()
.startActivity(whoThread, intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target != null ? target.mEmbeddedID : null,
requestCode, 0, null, null, options);

ActivityManagerNative.getDefault()就是获得一个ActivityManagerProxy对象,然后调用其.startActivity方法,这个方法继承自binder的native方法;
然而startActivity()里干了什么呢,首先对startActivityAsUser()进行调用,这时候一个ActivityStack已经构建出来了,然后通过
startActivityMayWait()方法对栈中的Activity进行遍历,对于这个ActivityStack,我的理解是需要进行ActivityManagerProxy管理的所有的Activity
的栈结构,然后根据intent进行Activity的筛选,进行启动准备,现在就已经有目标了,至于task的调度算法,过于复杂,就只等下回分解咯。
接下来发生的事情就如上面对于内核层的分析,其中startViaZygote()方法封装了fork进程的参数准备(正如我们在callstack看到的一样),要开fork进程
再通过zygoteSendArgsAndGetResult()方法将需求传递给zygote进程(通过socket进行监听)(又是一堆进程间ipc啊),待新进程fork出来后,zygote会把新进程的pid告诉给ActivityManagerService,这下才有的管理了咯。

0 0
原创粉丝点击