Android四大组件与进程启动关系总结
来源:互联网 发布:机械力学分析软件 编辑:程序博客网 时间:2024/06/05 01:08
Android四大组件与进程启动关系总结
进程创建方法
四大组件(Activity、Service、ContentProvider、Broadcast)在所属进程没有启动的情况下,在调用startActivity、startService、ContentResolver.query、processNextBroadcast方法后经过层层调用最终会调用到ActivityManagerService中的startProcessLocked方法。
进程创建时机
进程的创建时机分为以下两种情况
1.单进程应用
首先会为app创建进程,然后执行具体操作(启动一个Activity等)。如果app进程已创建则会在该进程执行具体操作。
2.多进程应用
在这种情况下,会为每个配置过android:process属性的组件创建进程,如果再起启动该组件,不会为其创建进程。启动其他未配置process属性的组件,还是会先判断对应进程是否存在,不存在的话为此app创建进程。
详细流程
1.ActivityManagerService中的startProcessLocked方法中最终会调用Process.start()方法,此方法通过socket通信让Zygote进程为app创建一个新的进程,然后经过一系列调用最终会执行到ActivityThread.main方法
2.在Activity.main方法中,会为主线程创建Looper对象并且执行loop方法,也会创建一个ActivityThread对象并且执行thread.attach方法。
public static void main(String[] args) { ... //为主线程创建looper对象 Looper.prepareMainLooper(); ActivityThread thread = new ActivityThread(); //执行attach方法 thread.attach(false); if (sMainThreadHandler == null) { sMainThreadHandler = thread.getHandler(); } if (false) { Looper.myLooper().setMessageLogging(new LogPrinter(Log.DEBUG, "ActivityThread")); } // End of event ActivityThreadMain. Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); //执行轮询 Looper.loop(); throw new RuntimeException("Main thread loop unexpectedly exited");}
3.ActivityThread.attach方法中会调用AMP的attachApplication的方法(AMP-ActivityManagerProxy,app进程与system_server进程利用Binder进行跨进程通讯的client,system_server中的ActivityManagerService为对应的Server)关键代码如下
private void attach(boolean system) { ... //创建ActivityManagerProxy对象,ActivityManagerProxy 是ActivityManagerNative的内部类并且实现了IActivityManager接口 final IActivityManager mgr = ActivityManagerNative.getDefault(); try { mgr.attachApplication(mAppThread); } catch (RemoteException ex) { } ...}
其中mAppThread为ApplicationThread,ActivityThread的私有变量
//ApplicationThread实现了IApplicationThread接口ApplicationThread mAppThread = new ApplicationThread();
ApplicationThread是与ActivityMangerService进行利用Binder进行跨进程通讯的Server,对应的ActivityMangerService中也有与之对应的client–ApplicationThreadProxy
4.接下来是调用AMP.attachApplication方法
public void attachApplication(IApplicationThread app) throws RemoteException{ Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); data.writeInterfaceToken(IActivityManager.descriptor); data.writeStrongBinder(app.asBinder()); mRemote.transact(ATTACH_APPLICATION_TRANSACTION, data, reply, 0); reply.readException(); data.recycle(); reply.recycle();}
mRemote是ActivityMangerService转为的IBinder对象。mRemote调用transact方法进程跨进程通讯
5.下一步在AMN(AMN-ActivityManagerNative,ActivityMangerService继承AMN)中中执行
public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException { switch (code) { ... case ATTACH_APPLICATION_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); //app为ApplicationThreadProxy IApplicationThread app = ApplicationThreadNative.asInterface(data.readStrongBinder()); if (app != null) { //将调用AMS的attachApplication方法,AMS继承了AMN attachApplication(app); } reply.writeNoException(); return true; } }}
上一步传进来的是ApplicationThread对象,通过ApplicationThreadNative.asInterface( data.readStrongBinder())方法获取其对应的ATP,代码如下
public abstract class ApplicationThreadNative extends Binder implements IApplicationThread { ... static public IApplicationThread asInterface(IBinder obj) { if (obj == null) { return null; } IApplicationThread in = (IApplicationThread)obj.queryLocalInterface(descriptor); if (in != null) { return in; } return new ApplicationThreadProxy(obj); } ...}
6.AMS的attachApplication方法代码如下
//thread为ApplicationThreadProxypublic final void attachApplication(IApplicationThread thread) { synchronized (this) { int callingPid = Binder.getCallingPid(); final long origId = Binder.clearCallingIdentity(); attachApplicationLocked(thread, callingPid); Binder.restoreCallingIdentity(origId); }}
7.attachApplicationLocked中会完成AMS与app进程的绑定关键代码如下
private final boolean attachApplicationLocked(IApplicationThread thread, int pid) { ... thread.bindApplication( processName, appInfo, providers, app.instrumentationClass, profilerInfo, app.instrumentationArguments, app.instrumentationWatcher, app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, isRestrictedBackupMode || !normalMode, app.persistent, new Configuration(mConfiguration), app.compat, getCommonServicesLocked(app.isolated), mCoreSettingsObserver.getCoreSettingsLocked()); ...}
下一步将调用ApplicationThreadProxy的bindApplication方法
8.ApplicationThreadProxy通过bindApplication方法经过Binder跨进程通讯最终调用的ApplicationThreadNative的onTransact的方法中
//第5步中,通过asInterface获取ApplicationThreadProxy时会将对应的ApplicaitonThread传入,mRemote即为ApplicaitonThread的IBinder形式mRemote.transact(BIND_APPLICATION_TRANSACTION, data, null,IBinder.FLAG_ONEWAY);
9.经过上一步,终于回到了app进程中ATN的onTransact方法
public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException { switch (code) { ... case BIND_APPLICATION_TRANSACTION: { ... //将会调用ApplicaitonThread的bindApplication方法,ApplicaitonThread继承 ApplicationThreadNative(ATN) bindApplication(packageName, info, providers, testName, profilerInfo , testArgs,testWatcher, uiAutomationConnection , testMode, openGlTrace,restrictedBackupMode , persistent, config, compatInfo, services, coreSettings); return true; } .. }
10.ApplicationThread最终会使用ActivityThread中的H(handler)调用到ActivityThread中的handleBindApplication方法完成一系列初始化。至此进程启动完毕
总结
通过4大组件启动进程时,首先会完成app进程的创建,app进程创建完毕后会完成app进程与system_server中的ActivityManagerService的相互绑定(AMP.attachApplication、ATP.bindApplication)。这两个方法是通过Binder完成跨进程通讯。
因为ActivityMangerService管理所有app的生命周期,所以使用了代理模式,每个app绑定AMS时都是用的是AMS对应的代理类AMP,而AMP中的mRemote对应的都是AMS。相同的道理在AMS管理app时使用的是ATP,而ATP中的mRemote则是ATP对应的AT。ATP与AMP是Binder的client端,AMS与AT是对应的Sever。
参考链接:
http://gityuan.com/2016/10/09/app-process-create-2/
- Android四大组件与进程启动关系总结
- Android四大基本组件与生命周期 总结
- android四大组件总结
- android四大组件总结
- Android四大组件总结
- Android总结:四大组件
- Android 四大组件(总结)
- android四大组件总结
- Android四大组件启动分析
- Android 四大组件之Service 的生命周期与启动Service
- android四大组件(详细总结)
- android四大组件(详细总结)
- android四大组件(详细总结)
- android四大组件(详细总结)
- android四大组件(详细总结)
- android四大组件(详细总结)
- android四大组件(详细总结)
- android四大组件(详细总结)
- R语言绘制精美PCoA图
- vs工程 "生成事件" "自定义生成步骤"
- Caffe模型测试之分类错误分析
- log4j2使用详解
- Freeline
- Android四大组件与进程启动关系总结
- PAT-A-1034. Head of a Gang (30)
- html,css,js加载顺序
- 长牌游戏开发--搭建系统环境
- 内存对齐分配策略(含位域模式)
- SpringBoot 在启动时运行代码
- JavaScript学习笔记(第一天)
- jQuery
- iptables