Activity启动过程
Android-7-1-2-Android-N-Activity启动流程分析
一篇文章看明白 Android 从点击应用图标到界面显示的过程
Android进程启动流程(App启动)
Android 应用点击图标到Activity界面显示的过程分析
应用的安装过程
应用安装的时候,通过PMS解析apk的AndroidManifest.xml文件,提取出这个apk的信息写入到packages.xml文件中,这些信息包括:权限、应用包名、icon、APK的安装位置、版本、userID等等。packages.xml文件位于系统目录下/data/system/packages.xml。
系统启动开启的服务
系统的会在启动时也可以认为开机时启动常用的服务,如ActivityManagerService(AMS),PackageManagerService(PMS),WindowManagerService(WMS),以及ServiceManager(SM),用于管理各种服务。
同时桌面Launcher会为安装过的应用生成不同的应用入口,对应桌面上的应用图标,下面分析点击应用图标的到应用启动的过程。
基础知识
AIDL
首先我们要理解AIDL的基础知识,AIDL的用法我们必须了然于胸,然后可以通过用法,来记住他们的关系。
- AIDL是标准的cs架构,所以分为c端和s端
- s端
- 新建一个MyAidlInterface.aidl文件,点击make project,生成一个IMyAidlInterface.java文件
- IMyAidlInterface.java的结构
—— IMyAidlInterface extends android.os.IInterface
—— abstract Stub extends Binder implements IMyAidlInterface Stub是一个抽象类,里面是没有实现IMyAidlInterface的相关接口的,需要子类来实现,如MyBinder
—— Proxy implements IMyAidlInterface
主要包含这三部分 - MyBinder extends IMyAidlInterface.Stub
- MyService extends Service,并在onBind()回调的时候返回MyBinder
- c端
- 复制MyAidlInterface.aidl文件到相同目录,并且也make project
- bindService(tIntent, mServiceConnection, BIND_AUTO_CREATE);
- IBinder转换为IMyAidlInterface,然后使用IMyAidlInterface调用相关接口即可
1@Override 2public void onServiceConnected(ComponentName name, IBinder service) { 3IMyAidlInterface mAidlInterface = IMyAidlInterface.Stub.asInterface(service); 4}
在c端调用asInterface()返回得意Proxy对象
通过这些用法,我们来看他们的关系
- s端使用的是IMyAidlInterface.Stub,其实就是MyBinder
- s端提供具体的能力实现MyBinder extends IMyAidlInterface.Stub
- c端最后调用调用的是IMyAidlInterface.Stub.Proxy
- IMyAidlInterface.Stub.Proxy是MyBinder extends IMyAidlInterface.Stub在c端使用的s端代理
- MyBinder是IMyAidlInterface.Stub的具体实现,都是extends Binder
也就是说,IMyAidlInterface.Stub是c端和s端的桥梁。
启动过程
- ActivityManagerService,简称AMS,服务端对象,负责系统中所有Activity的生命周期。相当于MyBinder extends IMyAidlInterface.Stub,自己在服务端写的那个具体提供服务的
- ActivityManagerNative继承Java的Binder类,同时实现了IActivityManager接口,即ActivityManagerNative将作为Binder通信的服务端为用户提供支持。相当于IMyAidlInterface.Stub,AIDL系统生成的
- ActivityManagerProxy:在ActivityManagerNative类中定义了内部类ActivityManagerProxy,该类同样实现了IActivityManager接口,将作为客户端使用的服务端代理。相当于IMyAidlInterface.Stub.Proxy,AIDL系统生成的
- ActivityThread,App的真正入口。当开启App之后,会调用main()开始运行,开启消息循环队列,这就是传说中的UI线程或者叫主线程。与ActivityManagerServices配合,一起完成Activity的管理工作
- ApplicationThread,用来实现ActivityManagerService与ActivityThread之间的交互。在ActivityManagerService需要管理相关Application中的Activity的生命周期时,通过ApplicationThread的代理对象与ActivityThread通讯。AIDL中类似于ActivityManagerService
- ApplicationThreadNative继承Java的Binder类,同时实现了IApplicationThread接口,即ApplicationThreadNative将作为Binder通信中客户端与服务端的桥梁。AIDL中类似于ActivityManagerNative
- ApplicationThreadProxy,是ApplicationThread在服务器端的客户端代理,负责和客户端的ApplicationThread通讯。AMS就是通过该代理与ActivityThread进行通信的。AIDL中类似于ActivityManagerProxy
- Instrumentation,每一个应用程序只有一个Instrumentation对象,每个Activity内都有一个对该对象的引用。Instrumentation可以理解为应用进程的管家,ActivityThread要创建或暂停某个Activity时,都需要通过Instrumentation来进行具体的操作。
- ActivityStack,Activity在AMS的栈管理,用来记录已经启动的Activity的先后关系,状态信息等。通过ActivityStack决定是否需要启动新的进程。
- ActivityRecord,ActivityStack的管理对象,每个Activity在AMS对应一个ActivityRecord,来记录Activity的状态以及其他的管理信息。其实就是服务器端的Activity对象的映像。
- TaskRecord,AMS抽象出来的一个”任务”的概念,是记录ActivityRecord的栈,一个”Task”包含若干个ActivityRecord。AMS用TaskRecord确保Activity启动和退出的顺序。如果你清楚Activity的4种launchMode,那么对这个概念应该不陌生。。
系统的AIDL
Android基础之IPC
IMyAidlInterface.aidl
1interface IMyAidlInterface { 2 String getName(); 3}
平常生成的AIDL
1package io.github.trylovecatch.aidlserver; 2// Declare any non-default types here with import statements 3public interface IMyAidlInterface extends android.os.IInterface { 4 /** 5 * Local-side IPC implementation stub class. 6 */ 7 public static abstract class Stub extends android.os.Binder 8 implements io.github.trylovecatch.aidlserver.IMyAidlInterface { 9 private static final java.lang.String DESCRIPTOR = "io.github.trylovecatch.aidlserver.IMyAidlInterface"; 10 /** 11 * Construct the stub at attach it to the interface. 12 */ 13 public Stub() { 14 this.attachInterface(this, DESCRIPTOR); 15 } 16 /** 17 * Cast an IBinder object into an io.github.trylovecatch.aidlserver.IMyAidlInterface interface, 18 * generating a proxy if needed. 19 */ 20 public static io.github.trylovecatch.aidlserver.IMyAidlInterface asInterface(android.os.IBinder obj) { 21 if ((obj == null)) { 22 return null; 23 } 24 android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR); 25 if (((iin != null) && (iin instanceof io.github.trylovecatch.aidlserver.IMyAidlInterface))) { 26 return ((io.github.trylovecatch.aidlserver.IMyAidlInterface) iin); 27 } 28 return new io.github.trylovecatch.aidlserver.IMyAidlInterface.Stub.Proxy(obj); 29 } 30 @Override 31 public android.os.IBinder asBinder() { 32 return this; 33 } 34 @Override 35 public boolean onTransact[træn'zækt](int code, android.os.Parcel data, android.os.Parcel reply, int flags) 36 throws android.os.RemoteException { 37 switch (code) { 38 case INTERFACE_TRANSACTION: { 39 reply.writeString(DESCRIPTOR); 40 return true; 41 } 42 case TRANSACTION_getName: { 43 data.enforceInterface(DESCRIPTOR); 44 java.lang.String _result = this.getName(); 45 reply.writeNoException(); 46 reply.writeString(_result); 47 return true; 48 } 49 } 50 return super.onTransact(code, data, reply, flags); 51 } 52 private static class Proxy implements io.github.trylovecatch.aidlserver.IMyAidlInterface { 53 private android.os.IBinder mRemote; 54 Proxy(android.os.IBinder remote) { 55 mRemote = remote; 56 } 57 @Override 58 public android.os.IBinder asBinder() { 59 return mRemote; 60 } 61 public java.lang.String getInterfaceDescriptor() { 62 return DESCRIPTOR; 63 } 64 @Override 65 public java.lang.String getName() throws android.os.RemoteException { 66 android.os.Parcel _data = android.os.Parcel.obtain(); 67 android.os.Parcel _reply = android.os.Parcel.obtain(); 68 java.lang.String _result; 69 try { 70 _data.writeInterfaceToken(DESCRIPTOR); 71 mRemote.transact(Stub.TRANSACTION_getName, _data, _reply, 0); 72 _reply.readException(); 73 _result = _reply.readString(); 74 } finally { 75 _reply.recycle(); 76 _data.recycle(); 77 } 78 return _result; 79 } 80 } 81 static final int TRANSACTION_getName = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0); 82 } 83 public java.lang.String getName() throws android.os.RemoteException; 84} 85
服务端的能力:
1class MyBinder extends IMyAidlInterface.Stub { 2 @Override 3 public String getName() throws RemoteException 4 { 5 return "哈哈哈"; 6 } 7}
ActivityManager
IActivityManager
IActivityManager源码
1public interface IActivityManager extends IInterface { 2 public int startActivity(...) throws RemoteException; 3 public void activityPaused(IBinder token) throws RemoteException; 4 public void attachApplication(IApplicationThread app) throws RemoteException; 5 ... 6}
ActivityManagerNative
ActivityManagerNative源码
注意:这是一个抽象类
1public abstract class ActivityManagerNative extends Binder implements IActivityManager 2{ 3 public ActivityManagerNative() { 4 attachInterface(this, descriptor); 5 } 6 static public IActivityManager asInterface(IBinder obj) { 7 if (obj == null) { 8 return null; 9 } 10 IActivityManager in = 11 (IActivityManager)obj.queryLocalInterface(descriptor); 12 if (in != null) { 13 return in; 14 } 15 return new ActivityManagerProxy(obj); 16 } 17 static public IActivityManager getDefault() { 18 return gDefault.get(); 19 } 20 private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() { 21 protected IActivityManager create() { 22 IBinder b = ServiceManager.getService("activity"); 23 if (false) { 24 Log.v("ActivityManager", "default service binder = " + b); 25 } 26 IActivityManager am = asInterface(b); 27 if (false) { 28 Log.v("ActivityManager", "default service = " + am); 29 } 30 return am; 31 } 32 }; 33} 34 @Override 35 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 36 throws RemoteException { 37 switch (code) { 38 case START_ACTIVITY_TRANSACTION: 39 { 40 ... 41 int result = startActivity(app, callingPackage, intent, resolvedType, resultTo, resultWho, requestCode, startFlags, profilerInfo, options); 42 ... 43 } 44 case ACTIVITY_PAUSED_TRANSACTION: { 45 data.enforceInterface(IActivityManager.descriptor); 46 IBinder token = data.readStrongBinder(); 47 activityPaused(token); 48 reply.writeNoException(); 49 return true; 50 } 51 case ATTACH_APPLICATION_TRANSACTION: { 52 data.enforceInterface(IActivityManager.descriptor); 53 IApplicationThread app = ApplicationThreadNative.asInterface(data.readStrongBinder()); 54 if (app != null) { 55 attachApplication(app); 56 } 57 reply.writeNoException(); 58 return true; 59 } 60 ... 61 } 62 return super.onTransact(code, data, reply, flags); 63 } 64 public IBinder asBinder() { 65 return this; 66 } 67}
ActivityManagerProxy
ActivityManagerProxy是ActivityManagerNative的一个内部类,这里单独拿出来。跟咱们系统生产的AIDL是一样的。
1class ActivityManagerProxy implements IActivityManager 2{ 3 public ActivityManagerProxy(IBinder remote) 4 { 5 mRemote = remote; 6 } 7 public IBinder asBinder() 8 { 9 return mRemote; 10 } 11 public int startActivity(...) throws RemoteException { 12 Parcel data = Parcel.obtain(); 13 Parcel reply = Parcel.obtain(); 14 ... 15 mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0); 16 reply.readException(); 17 int result = reply.readInt(); 18 reply.recycle(); 19 data.recycle(); 20 return result; 21 } 22 public void activityPaused(IBinder token) throws RemoteException 23 { 24 Parcel data = Parcel.obtain(); 25 Parcel reply = Parcel.obtain(); 26 data.writeInterfaceToken(IActivityManager.descriptor); 27 data.writeStrongBinder(token); 28 mRemote.transact(ACTIVITY_PAUSED_TRANSACTION, data, reply, 0); 29 reply.readException(); 30 data.recycle(); 31 reply.recycle(); 32 } 33 public void attachApplication(IApplicationThread app) throws RemoteException 34 { 35 Parcel data = Parcel.obtain(); 36 Parcel reply = Parcel.obtain(); 37 data.writeInterfaceToken(IActivityManager.descriptor); 38 data.writeStrongBinder(app.asBinder()); 39 mRemote.transact(ATTACH_APPLICATION_TRANSACTION, data, reply, 0); 40 reply.readException(); 41 data.recycle(); 42 reply.recycle(); 43 } 44 .... 45}
ActivityManagerService
ActivityManagerService源码
1public final class ActivityManagerService extends ActivityManagerNative { 2 ... 3 @Override 4 public final int startActivity(...) { 5 return startActivityAsUser(...); 6 } 7 @Override 8 public final void activityPaused(IBinder token) { 9 final long origId = Binder.clearCallingIdentity(); 10 synchronized(this) { 11 ActivityStack stack = ActivityRecord.getStackLocked(token); 12 if (stack != null) { 13 stack.activityPausedLocked(token, false); 14 } 15 } 16 Binder.restoreCallingIdentity(origId); 17 } 18 @Override 19 public final void attachApplication(IApplicationThread thread) { 20 synchronized (this) { 21 int callingPid = Binder.getCallingPid(); 22 final long origId = Binder.clearCallingIdentity(); 23 attachApplicationLocked(thread, callingPid); 24 Binder.restoreCallingIdentity(origId); 25 } 26 } 27 ... 28}
ApplicationThread
IApplicationThread
1public interface IApplicationThread extends IInterface { 2 void schedulePauseActivity(IBinder token, boolean finished, boolean userLeaving, int configChanges, boolean dontReport) throws RemoteException; 3 void scheduleStopActivity(IBinder token, boolean showWindow, int configChanges) throws RemoteException; 4 void scheduleLaunchActivity(...) throws RemoteException; 5 void bindApplication(...) throws RemoteException; 6}
ApplicationThreadNative
ApplicationThreadNative源码
注意:这是一个抽象类
1public abstract class ApplicationThreadNative extends Binder 2 implements IApplicationThread { 3 static public IApplicationThread asInterface(IBinder obj) { 4 if (obj == null) { 5 return null; 6 } 7 IApplicationThread in = 8 (IApplicationThread)obj.queryLocalInterface(descriptor); 9 if (in != null) { 10 return in; 11 } 12 return new ApplicationThreadProxy(obj); 13 } 14 public ApplicationThreadNative() { 15 attachInterface(this, descriptor); 16 } 17 @Override 18 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException { 19 switch (code) { 20 case SCHEDULE_PAUSE_ACTIVITY_TRANSACTION: 21 { 22 data.enforceInterface(IApplicationThread.descriptor); 23 IBinder b = data.readStrongBinder(); 24 boolean finished = data.readInt() != 0; 25 boolean userLeaving = data.readInt() != 0; 26 int configChanges = data.readInt(); 27 boolean dontReport = data.readInt() != 0; 28 schedulePauseActivity(b, finished, userLeaving, configChanges, dontReport); 29 return true; 30 } 31 case SCHEDULE_STOP_ACTIVITY_TRANSACTION: 32 { 33 data.enforceInterface(IApplicationThread.descriptor); 34 IBinder b = data.readStrongBinder(); 35 boolean show = data.readInt() != 0; 36 int configChanges = data.readInt(); 37 scheduleStopActivity(b, show, configChanges); 38 return true; 39 } 40 case SCHEDULE_LAUNCH_ACTIVITY_TRANSACTION: 41 { 42 ... 43 scheduleLaunchActivity(intent, b, ident, info, curConfig, overrideConfig, compatInfo, 44 referrer, voiceInteractor, procState, state, persistentState, ri, pi, 45 notResumed, isForward, profilerInfo); 46 return true; 47 } 48 case BIND_APPLICATION_TRANSACTION: 49 { 50 ... 51 bindApplication(...); 52 return true; 53 } 54 } 55 public IBinder asBinder() 56 { 57 return this; 58 } 59}
ApplicationThreadProxy
同样的,ApplicationThreadProxy也是ApplicationThreadNative的内部类
1class ApplicationThreadProxy implements IApplicationThread { 2 private final IBinder mRemote; 3 public ApplicationThreadProxy(IBinder remote) { 4 mRemote = remote; 5 } 6 public final IBinder asBinder() { 7 return mRemote; 8 } 9 public final void schedulePauseActivity(IBinder token, boolean finished, boolean userLeaving, int configChanges, boolean dontReport) throws RemoteException { 10 Parcel data = Parcel.obtain(); 11 data.writeInterfaceToken(IApplicationThread.descriptor); 12 data.writeStrongBinder(token); 13 data.writeInt(finished ? 1 : 0); 14 data.writeInt(userLeaving ? 1 :0); 15 data.writeInt(configChanges); 16 data.writeInt(dontReport ? 1 : 0); 17 mRemote.transact(SCHEDULE_PAUSE_ACTIVITY_TRANSACTION, data, null, IBinder.FLAG_ONEWAY); 18 data.recycle(); 19 } 20 public final void scheduleStopActivity(IBinder token, boolean showWindow, int configChanges) throws RemoteException { 21 Parcel data = Parcel.obtain(); 22 data.writeInterfaceToken(IApplicationThread.descriptor); 23 data.writeStrongBinder(token); 24 data.writeInt(showWindow ? 1 : 0); 25 data.writeInt(configChanges); 26 mRemote.transact(SCHEDULE_STOP_ACTIVITY_TRANSACTION, data, null, IBinder.FLAG_ONEWAY); 27 data.recycle(); 28 } 29 public final void scheduleLaunchActivity(...) throws RemoteException { 30 ... 31 mRemote.transact(SCHEDULE_LAUNCH_ACTIVITY_TRANSACTION, data, null, IBinder.FLAG_ONEWAY); 32 data.recycle(); 33 } 34 public final void bindApplication(...) throws RemoteException { 35 mRemote.transact(BIND_APPLICATION_TRANSACTION, data, null, 36 IBinder.FLAG_ONEWAY); 37 data.recycle(); 38 } 39 ... 40}
ApplicationThread
ActivityThread的源码
ApplicationThread是ActivityThread的内部类
1private class ApplicationThread extends ApplicationThreadNative { 2 public final void schedulePauseActivity(IBinder token, boolean finished, boolean userLeaving, int configChanges, boolean dontReport) { 3 sendMessage( 4 finished ? H.PAUSE_ACTIVITY_FINISHING : H.PAUSE_ACTIVITY, 5 token, 6 (userLeaving ? 1 : 0) | (dontReport ? 2 : 0), 7 configChanges); 8 } 9 public final void scheduleStopActivity(IBinder token, boolean showWindow, int configChanges) { 10 sendMessage( 11 showWindow ? H.STOP_ACTIVITY_SHOW : H.STOP_ACTIVITY_HIDE, 12 token, 0, configChanges); 13 } 14 public final void scheduleLaunchActivity(...) { 15 updateProcessState(procState, false); 16 ActivityClientRecord r = new ActivityClientRecord(); 17 r.token = token; 18 r.ident = ident; 19 r.intent = intent; 20 r.referrer = referrer; 21 r.voiceInteractor = voiceInteractor; 22 r.activityInfo = info; 23 r.compatInfo = compatInfo; 24 r.state = state; 25 r.persistentState = persistentState; 26 r.pendingResults = pendingResults; 27 r.pendingIntents = pendingNewIntents; 28 r.startsNotResumed = notResumed; 29 r.isForward = isForward; 30 r.profilerInfo = profilerInfo; 31 r.overrideConfig = overrideConfig; 32 updatePendingConfiguration(curConfig); 33 sendMessage(H.LAUNCH_ACTIVITY, r); 34 } 35 public final void bindApplication(...) { 36 if (services != null) { 37 // Setup the service cache in the ServiceManager 38 ServiceManager.initServiceCache(services); 39 } 40 setCoreSettings(coreSettings); 41 IPackageManager pm = getPackageManager(); 42 android.content.pm.PackageInfo pi = null; 43 try { 44 pi = pm.getPackageInfo(appInfo.packageName, 0, UserHandle.myUserId()); 45 } catch (RemoteException e) { 46 } 47 if (pi != null) { 48 boolean sharedUserIdSet = (pi.sharedUserId != null); 49 boolean processNameNotDefault = 50 (pi.applicationInfo != null && 51 !appInfo.packageName.equals(pi.applicationInfo.processName)); 52 boolean sharable = (sharedUserIdSet || processNameNotDefault); 53 // Tell the VMRuntime about the application, unless it is shared 54 // inside a process. 55 if (!sharable) { 56 VMRuntime.registerAppInfo(appInfo.packageName, appInfo.dataDir, appInfo.processName); 57 } 58 } 59 AppBindData data = new AppBindData(); 60 data.processName = processName; 61 data.appInfo = appInfo; 62 data.providers = providers; 63 data.instrumentationName = instrumentationName; 64 data.instrumentationArgs = instrumentationArgs; 65 data.instrumentationWatcher = instrumentationWatcher; 66 data.instrumentationUiAutomationConnection = instrumentationUiConnection; 67 data.debugMode = debugMode; 68 data.enableOpenGlTrace = enableOpenGlTrace; 69 data.restrictedBackupMode = isRestrictedBackupMode; 70 data.persistent = persistent; 71 data.config = config; 72 data.compatInfo = compatInfo; 73 data.initProfilerInfo = profilerInfo; 74 sendMessage(H.BIND_APPLICATION, data); 75 } 76 ... 77}
总结
- IActivityManager 都继承IInterface,等价于生成的AIDL文件的最外层IMyAidlInterface
- ActivityManagerNative extends Binder implements IActivityManager
等价于IMyAidlInterface.Stub,提供了跨进程的能力。它这是一个抽象类。- ActivityManagerProxy implements IActivityManager
等价于IMyAidlInterface.Stub.Proxy,这个是在客户端存在的,客户端调用它的方法,然后通过BinderProxy的transact()来实现IPC通信,并回调ActivityManagerNative的onTransact(),最终调用ActivityManagerService的对应方法。- ActivityManagerService extends ActivityManagerNative
等价于MyBinder extends IMyAidlInterface.Stub,是具体的服务端能提供的能力
ApplicationThread相关的也同理。
- IApplicationThread 对应 IActivityManager
- ApplicationThread 对应 ActivityManagerService
- ApplicationThreadNative 对应 ActivityManagerNative
- ApplicationThreadProxy 对应 ActivityManagerProxy
他俩的不同在于:ApplicationThread是App进程是服务端,system_server进程是客户端;ActivityManager是system_server进程是服务端,App进程是客户端。
asBinder
在ActivityManagerProxy里面
1public void attachApplication(IApplicationThread app) throws RemoteException 2 { 3 Parcel data = Parcel.obtain(); 4 Parcel reply = Parcel.obtain(); 5 data.writeInterfaceToken(IActivityManager.descriptor); 6 data.writeStrongBinder(app.asBinder()); 7 mRemote.transact(ATTACH_APPLICATION_TRANSACTION, data, reply, 0); 8 reply.readException(); 9 data.recycle(); 10 reply.recycle(); 11 }
ActivityManagerProxy是在App进程使用的,所以app.asBinder()其实是调用了IApplicationThread的asBinder(),相当于返回了ApplicationThread.this;
然后通过进程间通信,会回调ActivityManagerNative里面的onTransact(),如下:
1case ATTACH_APPLICATION_TRANSACTION: { 2 data.enforceInterface(IActivityManager.descriptor); 3 IApplicationThread app = ApplicationThreadNative.asInterface(data.readStrongBinder()); 4 if (app != null) { 5 attachApplication(app); 6 } 7 reply.writeNoException(); 8 return true; 9}
又调用了ApplicationThreadNative.asInterface静态方法,这样就返回了ApplicationThreadProxy对象了。
一般情况下,我们是通过调用bindService,然后ServiceConnection里面asInterface来获取Proxy对象的。不过我们也可以通过这种传递Binder对象的方式来获取到Proxy对象,就是需要手动调用asBinder对象。
Binder
平常,我们Binder的获取,是客户端调用bindService(),服务器onBinder返回的一个IBinder。
而这里,是通过客户端调用ActivityManagerNative.getDefault(),如下:
1private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() { 2 protected IActivityManager create() { 3 IBinder b = ServiceManager.getService("activity"); 4 if (false) { 5 Log.v("ActivityManager", "default service binder = " + b); 6 } 7 IActivityManager am = asInterface(b); 8 if (false) { 9 Log.v("ActivityManager", "default service = " + am); 10 } 11 return am; 12 } 13};
通过IBinder b = ServiceManager.getService("activity");这种方式获取的。这也是一个IPC通信,是App进程去service_manager进程查询服务,因为系统开机的时候,system_server进程已经去service_manager进程注册了一些服务,查询到之后会返回BinderProxy对象给App进程,然后调用asInterface得到ActivityManagerProxy对象。
bindService()
上面我们说:
平常,我们Binder的获取,是客户端调用bindService(),服务器onBinder返回的一个IBinder。
bindService()也是一个IPC过程,涉及到是三个进程 App进程、system_server进程、Service对应的服务进程。
App进程通知system_server进程要启动一个Service,system_server进程去启动这个服务进程(如果该进程不存在),类似于Activity启动流程,我们假设服务进程已经启动,那么我们需要启动Service,服务进程启动并且调用了onBind(),返回一个IBinder对象,因为就是在本地,所以应该是MyService对象;
然后会调用system_server进程AMS的publishService(),这个时候应该已经是BinderProxy对象了;
最后这个方法会IPC到App进程,调用onServiceConnected(),这个时候传入的是BinderProxy。
Task和Stack
Android系统中的每一个Activity都位于一个Task中。一个Task可以包含多个Activity,同一个Activity也可能有多个实例。 在AndroidManifest.xml中,我们可以通过android:launchMode来控制Activity在Task中的实例。
另外,在startActivity的时候,我们也可以通过setFlag 来控制启动的Activity在Task中的实例。
Task管理的意义还在于近期任务列表以及Back栈。 当你通过多任务键(有些设备上是长按Home键,有些设备上是专门提供的多任务键)调出多任务时,其实就是从ActivityManagerService获取了最近启动的Task列表。
Back栈管理了当你在Activity上点击Back键,当前Activity销毁后应该跳转到哪一个Activity的逻辑。关于Task和Back栈,请参见这里:Tasks and Back Stack。
其实在ActivityManagerService与WindowManagerService内部管理中,在Task之外,还有一层容器,这个容器应用开发者和用户可能都不会感觉到或者用到,但它却非常重要,那就是Stack。 下文中,我们将看到,Android系统中的多窗口管理,就是建立在Stack的数据结构上的。 一个Stack中包含了多个Task,一个Task中包含了多个Activity(Window),下图描述了它们的关系:
进程的创建
理解Android进程创建流程
图解:
App发起进程:当从桌面启动应用,则发起进程便是Launcher所在进程;当从某App内启动远程进程,则发送进程便是该App所在进程。发起进程先通过binder发送消息给system_server进程;
system_server进程:调用Process.start()方法,通过socket向zygote进程发送创建新进程的请求;
zygote进程:在执行ZygoteInit.main()后便进入runSelectLoop()循环体内,当有客户端连接时便会执行ZygoteConnection.runOnce()方法,再经过层层调用后fork出新的应用进程;
新进程:执行handleChildProc方法,最后调用ActivityThread.main()方法。
Zygote进程:是Android系统的首个Java进程,Zygote是所有Java进程的父进程,包括 system_server进程以及所有的App进程都是Zygote的子进程,注意这里说的是子进程,而非子线程。
点击应用图标
主要分为Launcher进程,system_server进程,Zygote进程,APP进程。
Launcher进程
在Launcher点击App图标:
Launcher.startActivitySafely
|
Launcher.startActivity
|
Activity.startActivity
|
Activity.startActivityForResult
|
Instrumentation.execStartActivity
|
ActivityManagerProxy.startActivity
|
mRemote.transact() mRemote为BinderProxy
Instrumentation.execStartActivity
我们来看下Instrumentation.execStartActivity
Android 6.0 Launcher 启动 Activity 过程源码分析
1public ActivityResult execStartActivity( 2 Context who, IBinder contextThread, IBinder token, Activity target, Intent intent, int requestCode, Bundle options) { 3 IApplicationThread whoThread = (IApplicationThread) contextThread; 4 // 省略部分代码 5 try { 6 intent.migrateExtraStreamToClipData(); 7 intent.prepareToLeaveProcess(); 8 int result = ActivityManagerNative.getDefault() 9 .startActivity(whoThread, who.getBasePackageName(), intent, intent.resolveTypeIfNeeded(who.getContentResolver()),token, target != null ? target.mEmbeddedID : null,requestCode, 0, null, options); 10 checkStartActivityResult(result, intent); 11 } catch (RemoteException e) { 12 throw new RuntimeException("Failure from system", e); 13 } 14 return null; 15}
参数类型 | 实际参数 | 含义 |
---|---|---|
Context who | this | Context 类 |
IBinder contextThread | mMainThread.getApplicationThread() | 自己的Binder本地对象 |
IBinder token | mToken | ActivityManagerService 中的ActivityRecord 代理对象 |
Activity target | this | 目标 |
Intent intent | intent | 组件信息 |
int requestCode | requestCode | 请求码 |
Bundle options | options | 附件信息 |
- contextThread 参数是一个 IBinder 类型,实际参数为mMainThread.getApplicationThread()。
ApplicationThread类是一个 Binder 类,那么它的作用是用来与 ActivityManagerService 通信的。
之前在 Binder 学习的时候,bindService 操作会在 onServiceConnected 返回 Service 的一个 Binder 对象,通过该 Binder 对象便可以执行 Service 中的函数,此时便完成的了 Activity 与 Service 的通信。
而现在,我们在 execStartActivity() 方法中把自己的 Binder 对象传递给 ActivityManagerService,不就是相当于 onServiceConnected 中回调 Binder 了嘛。
有了这个 Binder 对象,ActivityManagerService 才能够通知 Launcher 组件进入 Paused 状态。
- mToken类也是一个 Binder 类型,它是一个 Binder代理对象,它指向了 ActivityManagerService 中一个类型为 ActivityRecord的 Binder本地对象。每一个已经启动的 Activity 组件在 ActivityManagerService 中都有一个对应的ActivityRecord对象,用来维护对应的 Activity 组件的运行状态。将它传递给 ActivityManagerService,以便 ActivityManagerService 获得 Launcher 组件的详细信息了。
单例知识点
ActivityManagerProxy是AMS的本地代理,实际的工作是在远程AMS完成的
1public abstract class Singleton<T> { 2 private T mInstance; 3 protected abstract T create(); 4 public final T get() { 5 synchronized (this) { 6 if (mInstance == null) { 7 mInstance = create(); 8 } 9 return mInstance; 10 } 11 } 12}
1public abstract class ActivityManagerNative extends Binder implements IActivityManager{ 2 static public IActivityManager asInterface(IBinder obj) { 3 if (obj == null) { 4 return null; 5 } 6 IActivityManager in = 7 (IActivityManager)obj.queryLocalInterface(descriptor); 8 if (in != null) { 9 return in; 10 } 11 return new ActivityManagerProxy(obj); 12 } 13 static public IActivityManager getDefault() { 14 return gDefault.get(); 15 } 16 private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() { 17 protected IActivityManager create() { 18 // 通过 ServiceManager 来获得 ActivityServiceManager 的代理对象。 19 // 再通过 asInterface 方法判断是否为同一进程,不是,则封装成 ActivityManagerProxy 代理对象。 20 // ActivityManagerProxy 代理对象的操作都是由 ActivityServiceManager 的代理对象 Binder 来完成的。 21 // ActivityManagerProxy 只是在之上对数据封装了一层。 22 IBinder b = ServiceManager.getService("activity"); 23 if (false) { 24 Log.v("ActivityManager", "default service binder = " + b); 25 } 26 IActivityManager am = asInterface(b); 27 if (false) { 28 Log.v("ActivityManager", "default service = " + am); 29 } 30 return am; 31 } 32 }; 33}
ActivityManagerProxy.startActivity()
1public int startActivity(IApplicationThread caller, String callingPackage, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo, Bundle options) throws RemoteException { 2 Parcel data = Parcel.obtain(); 3 Parcel reply = Parcel.obtain(); 4 data.writeInterfaceToken(IActivityManager.descriptor); 5 // caller 参数为 Launcher 组件所运行的应用程序进程的 ApplicationThread Binder 本地对象。 6 data.writeStrongBinder(caller != null ? caller.asBinder() : null); 7 // Launcher 组件的包名 8 data.writeString(callingPackage); 9 // 需要启动的 Activity 组件的信息 10 intent.writeToParcel(data, 0); 11 data.writeString(resolvedType); 12 // ActivityManagerService 内部的 ActivityRecord 对象,保存了 Launcher 组件的详细信息。 13 data.writeStrongBinder(resultTo); 14 data.writeString(resultWho); 15 data.writeInt(requestCode); 16 data.writeInt(startFlags); 17 if (profilerInfo != null) { 18 data.writeInt(1); 19 profilerInfo.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE); 20 } else { 21 data.writeInt(0); 22 } 23 if (options != null) { 24 data.writeInt(1); 25 options.writeToParcel(data, 0); 26 } else { 27 data.writeInt(0); 28 } 29 mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0); 30 reply.readException(); 31 int result = reply.readInt(); 32 reply.recycle(); 33 data.recycle(); 34 return result; 35}
system_server进程
ActivityManagerNative.onTransact()
|
ActivityManagerService.startActivity()
|
ActivityStarter.startActivityMayWait()
|
ActivityStarter.startActivityLocked()
|
ActivityStarter.startActivityUnchecked()
|
ActivityStackSupervisor.resumeFocusedStackTopActivityLocked()
|
ActivityStack.resumeTopActivityUncheckedLocked()
|
ActivityStack.resumeTopActivityInnerLocked()
|
[if (mResumedActivity != null)]
ActivityStackSupervisor.pauseBackStacks()
|
ActivityStack.startPausingLocked()
|
[if (mResumedActivity == null)]
ActivityStack.startSpecificActivityLocked()
ActivityManagerNative.onTransact()
1public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2 throws RemoteException { 3 switch (code) { 4 case START_ACTIVITY_TRANSACTION: 5 { 6 ...... 7 int result = startActivity(app, callingPackage, intent, resolvedType,resultTo, resultWho, requestCode, startFlags, profilerInfo, options); 8 ...... 9 } 10 ...... 11 }
startActivity,就会调用我们自己实现的XXXService里面,也就是ActivityManagerService。
ActivityStack.resumeTopActivityInnerLocked()
1private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) { 2 ...... 3 // We need to start pausing the current activity so the top one can be resumed... 4 final boolean dontWaitForPause = (next.info.flags & FLAG_RESUME_WHILE_PAUSING) != 0; 5 boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving, next, dontWaitForPause); 6 if (mResumedActivity != null) { 7 pausing |= startPausingLocked(userLeaving, false, next, dontWaitForPause); 8 } 9 ...... 10 else { 11 ...... 12 mStackSupervisor.startSpecificActivityLocked(next, true, true); 13 } 14}
启动一个新Activity时,如果界面还存在其它的Activity,那么必须先中断其它的Activity。
因此,除了第一个启动的Home界面对应的Activity外,其它的Activity均需要进行此操作,当系统启动第一个Activity,即Home时,mResumedActivity的值才会为null。
经过一系列处理逻辑之后最终调用了startPausingLocked方法,这个方法作用就是让系统中栈中的Activity执行onPause方法。
ActivityStack.startPausingLocked()
1final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping, ActivityRecord resuming, boolean dontWait) { 2...... 3 try { 4 ...... 5 mService.updateUsageStats(prev, false); 6 prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing, userLeaving, prev.configChangeFlags, dontWait); 7 } 8...... 9}
可以看到这里执行了pre.app.thread.schedulePauseActivity方法,pre.app.thread就是ApplicationThreadProxy,根据以前的知识,很明显时一个IPC操作,这样就又切回了Launcher进程了。
Launcher进程
ApplicationThread.schedulePauseActivity()
|
ActivityThread.sendMessage()
|
ActivityThread.H.sendMessage()
|
ActivityThread.H.handleMessage()
|
ActivityThread.handlePauseActivity()
|
ActivityThread.performPauseActivity()
|
ActivityThread.performPauseActivityIfNeeded()
|
Instrumentation.callActivityOnPause()
|
Activity.performPause()
|
Activity.onPause()
|
ActivityManagerProxy.activityPaused()
|
mRemote.transact() mRemote为BinderProxy
ApplicationThread.schedulePauseActivity()
1public final void schedulePauseActivity(IBinder token, boolean finished, boolean userLeaving, int configChanges, boolean dontReport) { 2 int seq = getLifecycleSeq(); 3 if (DEBUG_ORDER) Slog.d(TAG, "pauseActivity " + ActivityThread.this + " operation received seq: " + seq); 4 sendMessage( finished ? H.PAUSE_ACTIVITY_FINISHING : H.PAUSE_ACTIVITY, token, (userLeaving ? USER_LEAVING : 0) | (dontReport ? DONT_REPORT : 0), configChanges, seq); 5}
ActivityThread.sendMessage()
1private void sendMessage(int what, Object obj, int arg1, int arg2, int seq) { 2 ...... 3 mH.sendMessage(msg); 4}
最终调用了mH的sendMessage方法,mH是在ActivityThread中定义的一个Handler对象,主要处理SystemServer进程的消息.
ActivityThread.H.handleMessage()
1public void handleMessage(Message msg) { 2 switch (msg.what) { 3 ...... 4 case PAUSE_ACTIVITY: { 5 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause"); 6 SomeArgs args = (SomeArgs) msg.obj; 7 handlePauseActivity((IBinder) args.arg1, false, 8 (args.argi1 & USER_LEAVING) != 0, args.argi2, 9 (args.argi1 & DONT_REPORT) != 0, args.argi3); 10 maybeSnapshot(); 11 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 12 } 13 break; 14 .... 15 } 16 .... 17 }
可以发现其调用了handlePauseActivity方法
ActivityThread.handlePauseActivity()
1private void handlePauseActivity(IBinder token, boolean finished, 2 boolean userLeaving, int configChanges, boolean dontReport, int seq) { 3 ActivityClientRecord r = mActivities.get(token); 4 ...... 5 performPauseActivity(token, finished, r.isPreHoneycomb(), "handlePauseActivity"); 6 ...... 7 // Tell the activity manager we have paused. 8 if (!dontReport) { 9 try { 10 ActivityManagerNative.getDefault().activityPaused(token); 11 } catch (RemoteException ex) { 12 throw ex.rethrowFromSystemServer(); 13 } 14 } 15 mSomeActivitiesChanged = true; 16 } 17}
方法体内部通过调用performPauseActivity方法来实现对栈顶Activity的onPause生命周期方法的回调.
ActivityThread.performPauseActivity()
1final Bundle performPauseActivity(ActivityClientRecord r, boolean finished, boolean saveState, String reason) { 2 ...... 3 performPauseActivityIfNeeded(r, reason); 4 ...... 5} 6private void performPauseActivityIfNeeded(ActivityClientRecord r, String reason) { 7 ...... 8 try { 9 r.activity.mCalled = false; 10 mInstrumentation.callActivityOnPause(r.activity); 11 ...... 12}
Instrumentation.callActivityOnPuase()
1public void callActivityOnPause(Activity activity) { 2 activity.performPause(); 3}
最终回调到了Activity的performPause方法:
Activity.performPause()
1final void performPause() { 2 mDoReportFullyDrawn = false; 3 mFragments.dispatchPause(); 4 mCalled = false; 5 onPause(); 6 mResumed = false; 7 if (!mCalled && getApplicationInfo().targetSdkVersion 8 >= android.os.Build.VERSION_CODES.GINGERBREAD) { 9 throw new SuperNotCalledException( 10 "Activity " + mComponent.toShortString() + 11 " did not call through to super.onPause()"); 12 } 13 mResumed = false; 14}
太不容易了,回调到了Activity的onPause方法,也就是说我们在启动一个Activity的时候最先被执行的是栈顶的Activity的onPause方法。记住这点吧,面试的时候经常会问到类似的问题。
然后回到我们的handlePauseActivity方法,在该方法的最后面执行了ActivityManagerNative.getDefault().activityPaused(token);方法,这是应用进程告诉服务进程,栈顶Activity已经执行完成onPause方法了,通过前面我们的分析,我们知道这句话会调用ctivityManagerProxy.activityPaused(),并最终会被ActivityManagerService的activityPaused方法执行。
ActivityManagerProxy.activityPaused()
1public void activityPaused(IBinder token) throws RemoteException { 2 Parcel data = Parcel.obtain(); 3 Parcel reply = Parcel.obtain(); 4 data.writeInterfaceToken(IActivityManager.descriptor); 5 data.writeStrongBinder(token); 6 mRemote.transact(ACTIVITY_PAUSED_TRANSACTION, data, reply, 0); 7 reply.readException(); 8 data.recycle(); 9 reply.recycle(); 10}
system_server进程
ActivityManagerService.activityPaused()
|
ActivityStack.activityPausedLocked()
|
ActivityStack.completePauseLocked()
|
ActivityStackSupervisor.resumeFocusedStackTopActivityLocked()
|
ActivityStack.resumeTopActivityUncheckedLocked()
|
ActivityStack.resumeTopActivityInnerLocked()
|
ActivityStackSupervisor.startSpecificActivityLocked()
ActivityManagerService.activityPaused()
1public final void activityPaused(IBinder token) { 2 final long origId = Binder.clearCallingIdentity(); 3 synchronized(this) { 4 ActivityStack stack = ActivityRecord.getStackLocked(token); 5 if (stack != null) { 6 stack.activityPausedLocked(token, false); 7 } 8 } 9 Binder.restoreCallingIdentity(origId); 10}
ActivityStack.completePauseLocked()
1private void completePauseLocked(boolean resumeNext, ActivityRecord resuming) { 2 ...... 3 if (resumeNext) { 4 final ActivityStack topStack = mStackSupervisor.getFocusedStack(); 5 if (!mService.isSleepingOrShuttingDownLocked()) { 6 mStackSupervisor.resumeFocusedStackTopActivityLocked(topStack, prev, null); 7 } else { 8 mStackSupervisor.checkReadyForSleepLocked(); 9 ActivityRecord top = topStack.topRunningActivityLocked(); 10 if (top == null || (prev != null && top != prev)) { 11 // If there are no more activities available to run, do resume anyway to start 12 // something. Also if the top activity on the stack is not the just paused 13 // activity, we need to go ahead and resume it to ensure we complete an 14 // in-flight app switch. 15 mStackSupervisor.resumeFocusedStackTopActivityLocked(); 16 } 17 } 18 } 19 ...... 20}
经过了一系列的逻辑之后,又调用了resumeTopActivityInnerLocked方法,又回到了这里,而这个时候
mResumedActivity != null,所以调用了ActivityStackSupervisor.startSpecificActivityLocked()
ActivityStackSupervisor.startSpecificActivityLocked()
1void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) { 2 // Is this activity's application already running? 3 ProcessRecord app = mService.getProcessRecordLocked(r.processName, r.info.applicationInfo.uid, true); 4 r.task.stack.setLaunchTime(r); 5 if (app != null && app.thread != null) { 6 try { 7 ...... 8 realStartActivityLocked(r, app, andResume, checkConfig); 9 return; 10 } catch (RemoteException e) { 11 Slog.w(TAG, "Exception when starting activity " 12 + r.intent.getComponent().flattenToShortString(), e); 13 } 14 // If a dead object exception was thrown -- fall through to 15 // restart the application. 16 } 17 mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0, 18 "activity", r.intent.getComponent(), false, false, true); 19}
可以发现在这个方法中,首先会判断一下需要启动的Activity所需要的应用进程是否已经启动,若启动的话,则直接调用realStartAtivityLocked方法,否则调用startProcessLocked方法,用于启动应用进程。
zygote进程
刚开始的时候,我们说过进程的创建,再来看一下,这张图:
1ActivityManagerService.startProcessLocked() 2| 3Process.start() 4| 5Process.startViaZygote() 6| 7Process.zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote) 8| 9ZygoteInit.runSelectLoop() 10| 11ZygoteConnection.runOnce() 12| 13fork()
ActivityManagerService.startProcessLocked()
1private final void startProcessLocked(ProcessRecord app, String hostingType,String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) { 2 ...... 3 // Start the process. It will either succeed and return a result containing 4 // the PID of the new process, or else throw a RuntimeException. 5 boolean isActivityProcess = (entryPoint == null); 6 if (entryPoint == null) entryPoint = "android.app.ActivityThread"; 7 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " + app.processName); 8 checkTime(startTime, "startProcess: asking zygote to start proc"); 9 Process.ProcessStartResult startResult = Process.start(entryPoint, app.processName, uid, uid, gids, debugFlags, mountExternal, app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet, app.info.dataDir, entryPointArgs); 10 checkTime(startTime, "startProcess: returned from zygote!"); 11 ...... 12}
注意:这个是在system_server进程里面
Process.start()
1private static ProcessStartResult startViaZygote(final String processClass, 2 final String niceName, 3 final int uid, final int gid, 4 final int[] gids, 5 int debugFlags, int mountExternal, 6 int targetSdkVersion, 7 String seInfo, 8 String abi, 9 String instructionSet, 10 String appDataDir, 11 String[] extraArgs) 12 throws ZygoteStartFailedEx { 13 synchronized(Process.class) { 14 ...... 15 return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote); 16 } 17}
Process.openZygoteSocketIfNeeded
1private static ZygoteState openZygoteSocketIfNeeded(String abi) throws ZygoteStartFailedEx { 2 if (primaryZygoteState == null || primaryZygoteState.isClosed()) { 3 try { 4 //向主zygote发起connect()操作 5 primaryZygoteState = ZygoteState.connect(ZYGOTE_SOCKET); 6 } catch (IOException ioe) { 7 ... 8 } 9 } 10 if (primaryZygoteState.matches(abi)) { 11 return primaryZygoteState; 12 } 13 if (secondaryZygoteState == null || secondaryZygoteState.isClosed()) { 14 //当主zygote没能匹配成功,则采用第二个zygote,发起connect()操作 15 secondaryZygoteState = ZygoteState.connect(SECONDARY_ZYGOTE_SOCKET); 16 } 17 if (secondaryZygoteState.matches(abi)) { 18 return secondaryZygoteState; 19 } 20 ... 21}
openZygoteSocketIfNeeded通过connect,来跟服务器建立socket链接,很类似我们自己写的socket。
注意:这个是在system_server进程里面。
后面的几个Process就不细说了,总之,接下来的流程就是,通过socket通道向Zygote进程发送一个参数列表,然后进入阻塞等待状态,直到远端的socket服务端发送回来新创建的进程pid才返回。
ZygoteInit.runSelectLoop()
说这个之前,我们先说下为什么会执行到这里。
Zygote进程是由由init进程而创建的,进程启动之后调用ZygoteInit.main()方法,预加载资源后,便调用runSelectLoop()方法。
就类似于咱们写的sorket,这个方法就是一个while(true)循环,一直等待着客户端连接
1public static void main(String argv[]) { 2 try { 3 runSelectLoop(abiList); 4 .... 5 } catch (MethodAndArgsCaller caller) { 6 caller.run(); 7 } catch (RuntimeException ex) { 8 closeServerSocket(); 9 throw ex; 10 } 11}
特别注意这里的catch (MethodAndArgsCaller caller),后面反射调用ActivityThread.main(),就是通过抛出这个异常来做的。
ZygoteConnection.runOnce()
1boolean runOnce() throws ZygoteInit.MethodAndArgsCaller { 2 String args[]; 3 Arguments parsedArgs = null; 4 FileDescriptor[] descriptors; 5 try { 6 //读取socket客户端发送过来的参数列表 7 args = readArgumentList(); 8 descriptors = mSocket.getAncillaryFileDescriptors(); 9 } catch (IOException ex) { 10 closeSocket(); 11 return true; 12 } 13 PrintStream newStderr = null; 14 if (descriptors != null && descriptors.length >= 3) { 15 newStderr = new PrintStream(new FileOutputStream(descriptors[2])); 16 } 17 int pid = -1; 18 FileDescriptor childPipeFd = null; 19 FileDescriptor serverPipeFd = null; 20 try { 21 //将binder客户端传递过来的参数,解析成Arguments对象格式 22 parsedArgs = new Arguments(args); 23 ... 24 int [] fdsToClose = { -1, -1 }; 25 FileDescriptor fd = mSocket.getFileDescriptor(); 26 if (fd != null) { 27 fdsToClose[0] = fd.getInt$(); 28 } 29 fd = ZygoteInit.getServerSocketFileDescriptor(); 30 if (fd != null) { 31 fdsToClose[1] = fd.getInt$(); 32 } 33 fd = null; 34 // 重点方法 35 pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids, 36 parsedArgs.debugFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo, 37 parsedArgs.niceName, fdsToClose, parsedArgs.instructionSet, 38 parsedArgs.appDataDir); 39 } catch (Exception e) { 40 ... 41 } 42 try { 43 if (pid == 0) { 44 //子进程执行 45 IoUtils.closeQuietly(serverPipeFd); 46 serverPipeFd = null; 47 //【见小节13】 48 handleChildProc(parsedArgs, descriptors, childPipeFd, newStderr); 49 // 不应到达此处,子进程预期的是抛出异常ZygoteInit.MethodAndArgsCaller或者执行exec(). 50 return true; 51 } else { 52 //父进程执行 53 IoUtils.closeQuietly(childPipeFd); 54 childPipeFd = null; 55 return handleParentProc(pid, descriptors, serverPipeFd, parsedArgs); 56 } 57 } finally { 58 IoUtils.closeQuietly(childPipeFd); 59 IoUtils.closeQuietly(serverPipeFd); 60 } 61}
- Zygote.forkAndSpecialize()这个是比较重要的方法,它会调用nativeForkAndSpecialize(),最后会调用我们熟悉的fork()来创建子进程。
- pid==0,说明是在子进程里面,就会调用handleChildProc,也就是说,这个是会在新进程里面执行的,后面会说到。
fork()
Android进程系列第一篇---进程基础
理解fork()的一次调用两次执行
fork函数执行一次,返回两次
返回值有3种类型。
- 父进程中,fork返回新创建的子进程的pid;
- 子进程中,fork返回0;
- 当出现错误时,fork返回负数。(当进程数超过上限或者系统内存不足时会出错)
怎么理解呢?我们看一个例子:
1#include <unistd.h> 2#include <stdio.h> 3#include <wait.h> 4int a; 5int main() { 6 int count = 0; 7 pid_t fpid = fork(); 8 if (fpid < 0) { 9 printf("创建父子进程失败!"); 10 } else if (fpid == 0) { 11 printf("子进程ID:%dn", getpid()); 12 count++; 13 a = 0; 14 } else { 15 printf("父进程ID:%dn", getpid()); 16 count=10; 17 a = 1; 18 } 19 printf("count=%dn", count); 20 printf("a=%dn", a); 21 waitpid(fpid, NULL, 0); 22 return 0; 23} 24*************************************************************** 25/home/wangjing/CLionProjects/untitled/cmake-build-debug/untitled 26父进程ID:15229 27count=10 28a=1 29子进程ID:15230 30count=1 31a=0 32Process finished with exit code 0
通过打印的结果,可以发现一些重要信息:
- fork函数执行一次,返回两次
- a是全局变量,count是局部变量,子进程和父进程同时操作,但是互相不受影响
- 进程id不一样了
所以说:
1、fork之后,会有两个进程,fork出了一个子进程
2、fork调用完成后,我们的main函数接下来要执行的代码,已经处于了两个不同的进程了,这两个进程都会继续执行剩下的代码,而且不同进程fork的返回值也不一样。
2、两个进程代码是同一份,但是数据却不是同一份
接下来,我们来解释为什么会共享代码?
进程在内存里有三部分的数据——代码段、堆栈段和数据段。这三个部分是构成一个完整的执行序列的必要的部分。
- 代码段,存放了程序代码的内存空间。
- 堆栈段,存放的返回地址、参数以及局部变量
- 数据段,存放程序的全局变量,常数以及动态数据分配的数据空间
1int a; 2void main() 3{ 4 int b; 5 int c=func(); 6} 7int func() 8{ 9 int d; 10 return 0; 11}
上面这个例子里面,变量b,c,d都是会存放在堆栈段里面,而a则会存放在数据段里
fork()总结:
- fork函数执行一次,返回两次
- fork函数之后的代码,子进程和父进程会同时执行,理解为从fork之后,子进程和父进程运行的是同一个程序
- fork出来的子进程和父进程,共用代码段,但是会拥有各自的数据段和堆栈段
App进程
我们前面说过,pid==0(即运行在子进程)继续开始执行handleChildProc()方法,所以我们从它开始。
ZygoteConnection.handleChildProc()
|
RuntimeInit.zygoteInit()
|
RuntimeInit.commonInit()
|
RuntimeInit.nativeZygoteInit()
|
RuntimeInit.applicationInit()
|
RuntimeInit.invokeStaticMain()
|
ZygoteInit.MethodAndArgsCaller()
|
MethodAndArgsCaller.run()
RuntimeInit.commonInit()
1private static final void commonInit() { 2 // 设置默认的未捕捉异常处理方法 3 Thread.setDefaultUncaughtExceptionHandler(new UncaughtHandler()); 4 // 设置市区,中国时区为"Asia/Shanghai" 5 TimezoneGetter.setInstance(new TimezoneGetter() { 6 public String getId() { 7 return SystemProperties.get("persist.sys.timezone"); 8 } 9 }); 10 TimeZone.setDefault(null); 11 //重置log配置 12 LogManager.getLogManager().reset(); 13 new AndroidConfig(); 14 // 设置默认的HTTP User-agent格式,用于 HttpURLConnection。 15 String userAgent = getDefaultUserAgent(); 16 System.setProperty("http.agent", userAgent); 17 // 设置socket的tag,用于网络流量统计 18 NetworkManagementSocketTagger.install(); 19}
- 设置默认的未捕捉异常处理方法
- 设置时区
- 设置默认的HTTP User-agent格式
RuntimeInit.nativeZygoteInit()
native方法
- 调用open()打开/dev/binder驱动设备,再利用mmap()映射内核的地址空间,将Binder驱动的fd赋值ProcessState对象中的变量mDriverFD,用于交互操作。
- 启动Binder线程池
RuntimeInit.applicationInit()
1private static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) throws ZygoteInit.MethodAndArgsCaller { 2 //true代表应用程序退出时不调用AppRuntime.onExit(),否则会在退出前调用 3 nativeSetExitWithoutCleanup(true); 4 //设置虚拟机的内存利用率参数值为0.75 5 VMRuntime.getRuntime().setTargetHeapUtilization(0.75f); 6 VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion); 7 final Arguments args; 8 try { 9 args = new Arguments(argv); //解析参数 10 } catch (IllegalArgumentException ex) { 11 return; 12 } 13 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 14 //调用startClass的static方法 main() 【见流程15】 15 invokeStaticMain(args.startClass, args.startArgs, classLoader); 16}
此处args.startClass为”android.app.ActivityThread”。
RuntimeInit.invokeStaticMain()
1private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader) throws ZygoteInit.MethodAndArgsCaller { 2 Class<?> cl = Class.forName(className, true, classLoader); 3 Method m = cl.getMethod("main", new Class[] { String[].class }); 4 int modifiers = m.getModifiers(); 5 ... 6 //通过抛出异常,回到ZygoteInit.main()。这样做好处是能清空栈帧,提高栈帧利用率。 7 throw new ZygoteInit.MethodAndArgsCaller(m, argv); 8}
这里m是main方法
上面我们说过:
1public static void main(String argv[]) { 2 try { 3 runSelectLoop(abiList); 4 .... 5 } catch (MethodAndArgsCaller caller) { 6 caller.run(); 7 } catch (RuntimeException ex) { 8 closeServerSocket(); 9 throw ex; 10 } 11}
通过抛出异常,回到ZygoteInit.main()。这样做好处是能清空栈帧,提高栈帧利用率。
这样,catch到之后,会调用MethodAndArgsCaller.run()。
MethodAndArgsCaller.run()
1public static class MethodAndArgsCaller extends Exception implements Runnable { 2 public void run() { 3 try { 4 //根据传递过来的参数,此处反射调用ActivityThread.main()方法 5 mMethod.invoke(null, new Object[] { mArgs }); 6 } catch (IllegalAccessException ex) { 7 throw new RuntimeException(ex); 8 } catch (InvocationTargetException ex) { 9 Throwable cause = ex.getCause(); 10 if (cause instanceof RuntimeException) { 11 throw (RuntimeException) cause; 12 } else if (cause instanceof Error) { 13 throw (Error) cause; 14 } 15 throw new RuntimeException(ex); 16 } 17 } 18}
根据传递过来的参数,此处反射调用ActivityThread.main()方法。
总算是进入到了ActivityThread类的main()方法。
App进程
ActivityThread.main()
|
ActivityThread.attach()
|
ActivityManagerProxy.attachApplication()
|
ActivityManagerNative.onTransact()
|
ActivityManagerService.attachApplication()
|
ActivityManagerService.attachApplicationLocked()
|
ApplicationThreadNative.ApplicationThreadProxy.bindApplication()
|
ApplicationThreadNative.onTransact()
|
ActivityThread.ApplicationThread.bindApplication()
|
ActivityThread.sendMessage()
|
ActivityThread.H.sendMessage()
|
ActivityThread.H.handleMessage()
|
ActivityThread.handleBindApplication()
ActivityThread.main()
1public static void main(String[] args) { 2 Looper.prepareMainLooper(); 3 //又新建一个ActivityThread并调用attach(false) 4 ActivityThread thread = new ActivityThread(); 5 thread.attach(false); 6 if (sMainThreadHandler == null) { 7 sMainThreadHandler = thread.getHandler(); 8 } 9}
注意此时只创建了应用程序的ActivityThread和ApplicationThread,和开启了Handler消息循环机制,其他的都还未创建。
ActivityThread.attach(false)又会最终到AMS的attachApplication,而attachApplication的主要作用就是将本地的ApplicationThread传递到AMS。
AMS通过ApplicationThread的代理ApplicationThreadProxy,来调用应用程序ApplicationThread.bindApplication,通知应用程序的ApplicationThread已和AMS绑定,可以不借助其他进程帮助直接通信了。此时Launcher的任务也算是完成了。
将信息放到应用里的消息队列里,通过Handler消息机制,在ActivityThread.handleMeaasge里处理H.BIND_APPLICATION的信息,调用AplicationThread.handleBindApplication
1handleBindApplication(AppBindData data) { 2 Process.setArgV0(data.processName);//设置进程名 3 ... 4 //初始化mInstrumentation 5 if(data.mInstrumentation!=null) { 6 mInstrumentation = (Instrumentation) cl.loadClass(data.instrumentationName.getClassName()).newInstance(); 7 }else { 8 mInstrumentation = new Instrumentation(); 9 } 10 //创建Application,data.info是个LoadedApk对象。 11 Application app = data.info.makeApplication(data.restrictedBackupMode, null); 12 mInitialApplication = app; 13 //调用Application的onCreate()方法。 14 mInstrumentation.callApplicationOnCreate(app); 15} 16LoadedApk类: 17public Application makeApplication(boolean forceDefaultAppClass,Instrumentation instrumentation) { 18 if (mApplication != null) { 19 return mApplication; 20 } 21 String appClass = mApplicationInfo.className; 22 java.lang.ClassLoader cl = getClassLoader(); 23 //此时新建一个Application的ContextImpl对象, 24 ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this); 25 //通过在handleBindApplication创建的mInstrumentation对象新建一个Application对象,同时进行attach。 26 app = mActivityThread.mInstrumentation.newApplication(cl, appClass, appContext); 27 appContext.setOuterContext(app); 28 } 29Instrumentation类: 30public Application newApplication(ClassLoader cl, String className, Context context) { 31 return newApplication(cl.loadClass(className), context); 32} 33Instrumentation类: 34static public Application newApplication(Class<?> clazz, Context context) { 35 //实例化Application 36 Application app = (Application)clazz.newInstance(); 37 // Application和context绑定 38 app.attach(context); 39 return app; 40} 41//attach就是将新建的ContextImpl赋值到mBase,这个ContextImpl对象就是所有Application内Context的具体 42//实现,同时赋值一些其他的信息如mLoadedApk。 43final void attach(Context context) { 44 mBase = base; 45 mLoadedApk = ContextImpl.getImpl(context).mPackageInfo; 46}
可以看出来,Instrumentation和Application,都是反射调用的:
1//初始化mInstrumentation 2if(data.mInstrumentation!=null) { 3 mInstrumentation = (Instrumentation) cl.loadClass(data.instrumentationName.getClassName()).newInstance(); 4}else { 5 mInstrumentation = new Instrumentation(); 6} 7//实例化Application 8Application app = (Application)clazz.newInstance();
Application创建完成之后,就会调用onCreate():
1//调用Application的onCreate()方法。 2mInstrumentation.callApplicationOnCreate(app);
本文来源于:面试进阶之Activity启动过程-变化吧门户
特别声明:以上文章内容仅代表作者本人观点,不代表变化吧门户观点或立场。如有关于作品内容、版权或其它问题请于作品发表后的30日内与变化吧联系。
- 赞助本站
- 微信扫一扫
-
- 加入Q群
- QQ扫一扫
-
评论