博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Activity的启动过程第三篇
阅读量:6153 次
发布时间:2019-06-21

本文共 3383 字,大约阅读时间需要 11 分钟。

上一篇 ,我们分析到了这里 //这里是真正打开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。

转载地址:http://bxbfa.baihongyu.com/

你可能感兴趣的文章
HTML 邮件链接,超链接发邮件
查看>>
HDU 5524:Subtrees
查看>>
手机端userAgent
查看>>
pip安装Mysql-python报错EnvironmentError: mysql_config not found
查看>>
http协议组成(请求状态码)
查看>>
怎样成为一个高手观后感
查看>>
[转]VC预处理指令与宏定义的妙用
查看>>
JQuery radio单选框应用
查看>>
MySql操作
查看>>
python 解析 XML文件
查看>>
MySQL 文件导入出错
查看>>
java相关
查看>>
由一个异常开始思考springmvc参数解析
查看>>
向上扩展型SSD 将可满足向外扩展需求
查看>>
虚机不能启动的特例思考
查看>>
SQL Server编程系列(1):SMO介绍
查看>>
在VMware网络测试“专用VLAN”功能
查看>>
使用Formik轻松开发更高质量的React表单(三)<Formik />解析
查看>>
也问腾讯:你把用户放在什么位置?
查看>>
CSS Sprites 样式生成工具(bg2css)
查看>>