上一篇 ,我们分析到了这里 //这里是真正打开Activity的地方 //这个ActivityManagerNative.getDefault()是AMS的代理对象,调用startActivity来将activity启动起来
int result = ActivityManagerNative.getDefault() .startActivity(whoThread, who.getBasePackageName(), intent, intent.resolveTypeIfNeeded(who.getContentResolver()), token, target != null ? target.mEmbeddedID : null, requestCode, 0, null, null, options);复制代码
通过这个我们ActivityManagerNative.getDefault的源码,我们也知道,这里实际上是获取了AndroidManagerService的代理对象。,AndroidManagerProxy,OK我们继续看下面。 继续深入到ActivityManagerNative.getDefault().startActivity()的方法中
class ActivityManagerProxy implements IActivityManager{ public int startActivity(IApplicationThread caller, String callingPackage, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, String profileFile, ParcelFileDescriptor profileFd, Bundle options) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); data.writeInterfaceToken(IActivityManager.descriptor); data.writeStrongBinder(caller != null ? caller.asBinder() : null); data.writeString(callingPackage); intent.writeToParcel(data, 0); data.writeString(resolvedType); data.writeStrongBinder(resultTo); data.writeString(resultWho); data.writeInt(requestCode); data.writeInt(startFlags); data.writeString(profileFile); if (profileFd != null) { data.writeInt(1); profileFd.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE); } else { data.writeInt(0); } if (options != null) { data.writeInt(1); options.writeToParcel(data, 0); } else { data.writeInt(0); } //这个remote是个Ibinder类型,负责进程通信,也就是和ActivityManagerService进行进程通信 mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0); reply.readException(); int result = reply.readInt(); reply.recycle(); data.recycle(); return result; }}复制代码
这里面主要做的事情,就是,把上面传回来的参数,写入Parcel的data中去,并发送一个类型为START_ACTIVITY_TRANSACTION的进程通信请求。这里面我们关注3个参数,caller ,Intent,和resultTo,参数caller指向了Launch组件所运行进程的ApplicationThread对象,参数Intent 包含了要启动Activity组件的详细信息,参数resultTo指向了AMS内部的ActivityRecord(这个类的作用是维护对应activity组件的运行信息)对象,它里面保存了Launcher的详细信息。OK到这里为止,都是在Launcher里面执行的,我们在回顾一下总的过程。
1、Laucher组件 首先向AMS(AndroidManagerService)发送一个启动Mainactivity的请求, 这个请求是进程间通信的。 2、AMS首先将要启动的MainActivity组件的信息保留起来,然后向Laucher组件发送一个进入终止状态的进程通信。 3、然后,Laucher组件会接收到AMS发来的中止请求,进入中止状态, 然后再向AMS发送消息,告诉AMS 我已经进入中止状态了,你请继续做你的是事情,这样AMS就能继续进行启动Aty的操作。 4、由于MainAty的启动是在Lauther程序中启动的,Lauther中止了,程序应用进程也就不存在了,然后AMS就会新启动一个应用进程。 5、新的应用进程启动后,就会告诉AMS 我(新的应用进程)已经启动好了,然后发一个通信请求给AMS。 6、接收到新应用进程发来的通信后,AMS就会把第二步保留的组件信息 传递给新的进程,然后新的进程就可以靠这些信息去启动MainAty。
到目前为止,我们已经分析了上面的前3个步骤。以上3个步骤都是Launcher和AMS交互的过程,然后来做一个小节。
前三步小节: 首先,Launcher会在PackageManagerService中寻找Main组件信息,然后将信息与对应APP图标关联起来,并将组件信息保存起来,然后就会调用 Activity的startActivity方法,之后又会调用Instrument的execStartActivity方法,Instrument主要作用于监控APP与系统之间的通信,在执行过execStartActivity方法后,Launcher就把Instrument(Activity的成员)传递给AMS,AMS接收到这个对象,就获取到了Launcher的信息,下一步就让Launcher进入停止状态。最后,也就是这篇提到的,Launcher通过发送mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0);这个类型的进程通信,把信息传给AMS,通知Launcher已经进入终止状态,然后接下来的启动过程交给AMS。