[关闭]
@TryLoveCatch 2022-05-04T16:43:13.000000Z 字数 44358 阅读 840

Android知识体系之应用启动流程

Android知识体系


应用的安装过程

应用安装的时候,通过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的用法我们必须了然于胸,然后可以通过用法,来记住他们的关系。

通过这些用法,我们来看他们的关系

也就是说,IMyAidlInterface.Stub是c端和s端的桥梁。

启动过程

系统的AIDL

Android基础之IPC

IMyAidlInterface.aidl

  1. interface IMyAidlInterface {
  2. String getName();
  3. }

平常生成的AIDL

  1. package io.github.trylovecatch.aidlserver;
  2. // Declare any non-default types here with import statements
  3. public 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. }

服务端的能力:

  1. class MyBinder extends IMyAidlInterface.Stub {
  2. @Override
  3. public String getName() throws RemoteException
  4. {
  5. return "哈哈哈";
  6. }
  7. }

ActivityManager

IActivityManager

IActivityManager源码

  1. public 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源码

注意:这是一个抽象类

  1. public 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是一样的。

  1. class 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源码

  1. public 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

  1. public 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源码

注意:这是一个抽象类

  1. public 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的内部类

  1. class 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的内部类

  1. private 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相关的也同理。

他俩的不同在于:ApplicationThread是App进程是服务端,system_server进程是客户端;ActivityManager是system_server进程是服务端,App进程是客户端。

asBinder

在ActivityManagerProxy里面

  1. public 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(),如下:

  1. case 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(),如下:

  1. private 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

ActivityRecord、TaskRecord、ActivityStack以及Activity启动模式详解
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图标:

  1. Launcher.startActivitySafely
  2. |
  3. Launcher.startActivity
  4. |
  5. Activity.startActivity
  6. |
  7. Activity.startActivityForResult
  8. |
  9. Instrumentation.execStartActivity
  10. |
  11. ActivityManagerProxy.startActivity
  12. |
  13. mRemote.transact() mRemoteBinderProxy

Instrumentation.execStartActivity

我们来看下Instrumentation.execStartActivity
Android 6.0 Launcher 启动 Activity 过程源码分析

  1. public 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 附件信息

之前在 Binder 学习的时候,bindService 操作会在 onServiceConnected 返回 Service 的一个 Binder 对象,通过该 Binder 对象便可以执行 Service 中的函数,此时便完成的了 Activity 与 Service 的通信。
而现在,我们在 execStartActivity() 方法中把自己的 Binder 对象传递给 ActivityManagerService,不就是相当于 onServiceConnected 中回调 Binder 了嘛。
有了这个 Binder 对象,ActivityManagerService 才能够通知 Launcher 组件进入 Paused 状态。

单例知识点

ActivityManagerProxy是AMS的本地代理,实际的工作是在远程AMS完成的

  1. public 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. }
  1. public 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()

  1. public 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进程

  1. ActivityManagerNative.onTransact()
  2. |
  3. ActivityManagerService.startActivity()
  4. |
  5. ActivityStarter.startActivityMayWait()
  6. |
  7. ActivityStarter.startActivityLocked()
  8. |
  9. ActivityStarter.startActivityUnchecked()
  10. |
  11. ActivityStackSupervisor.resumeFocusedStackTopActivityLocked()
  12. |
  13. ActivityStack.resumeTopActivityUncheckedLocked()
  14. |
  15. ActivityStack.resumeTopActivityInnerLocked()
  16. |
  17. [if (mResumedActivity != null)]
  18. ActivityStackSupervisor.pauseBackStacks()
  19. |
  20. ActivityStack.startPausingLocked()
  21. |
  22. [if (mResumedActivity == null)]
  23. ActivityStack.startSpecificActivityLocked()

ActivityManagerNative.onTransact()

  1. public 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()

  1. private 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()

  1. final 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进程

  1. ApplicationThread.schedulePauseActivity()
  2. |
  3. ActivityThread.sendMessage()
  4. |
  5. ActivityThread.H.sendMessage()
  6. |
  7. ActivityThread.H.handleMessage()
  8. |
  9. ActivityThread.handlePauseActivity()
  10. |
  11. ActivityThread.performPauseActivity()
  12. |
  13. ActivityThread.performPauseActivityIfNeeded()
  14. |
  15. Instrumentation.callActivityOnPause()
  16. |
  17. Activity.performPause()
  18. |
  19. Activity.onPause()
  20. |
  21. ActivityManagerProxy.activityPaused()
  22. |
  23. mRemote.transact() mRemoteBinderProxy

ApplicationThread.schedulePauseActivity()

  1. public 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()

  1. private 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()

  1. public 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()

  1. private 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()

  1. final Bundle performPauseActivity(ActivityClientRecord r, boolean finished, boolean saveState, String reason) {
  2. ......
  3. performPauseActivityIfNeeded(r, reason);
  4. ......
  5. }
  6. private void performPauseActivityIfNeeded(ActivityClientRecord r, String reason) {
  7. ......
  8. try {
  9. r.activity.mCalled = false;
  10. mInstrumentation.callActivityOnPause(r.activity);
  11. ......
  12. }

Instrumentation.callActivityOnPuase()

  1. public void callActivityOnPause(Activity activity) {
  2. activity.performPause();
  3. }

最终回调到了Activity的performPause方法:

Activity.performPause()

  1. final 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()

  1. public 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进程

  1. ActivityManagerService.activityPaused()
  2. |
  3. ActivityStack.activityPausedLocked()
  4. |
  5. ActivityStack.completePauseLocked()
  6. |
  7. ActivityStackSupervisor.resumeFocusedStackTopActivityLocked()
  8. |
  9. ActivityStack.resumeTopActivityUncheckedLocked()
  10. |
  11. ActivityStack.resumeTopActivityInnerLocked()
  12. |
  13. ActivityStackSupervisor.startSpecificActivityLocked()

ActivityManagerService.activityPaused()

  1. public 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()

  1. private 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()

  1. void 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进程

刚开始的时候,我们说过进程的创建,再来看一下,这张图:

  1. ActivityManagerService.startProcessLocked()
  2. |
  3. Process.start()
  4. |
  5. Process.startViaZygote()
  6. |
  7. Process.zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote)
  8. |
  9. ZygoteInit.runSelectLoop()
  10. |
  11. ZygoteConnection.runOnce()
  12. |
  13. fork()

ActivityManagerService.startProcessLocked()

  1. private 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()

  1. private 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

  1. private 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)循环,一直等待着客户端连接

  1. public 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()

  1. boolean 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. }
  1. Zygote.forkAndSpecialize()这个是比较重要的方法,它会调用nativeForkAndSpecialize(),最后会调用我们熟悉的fork()来创建子进程。
  2. 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>
  4. int a;
  5. int main() {
  6. int count = 0;
  7. pid_t fpid = fork();
  8. if (fpid < 0) {
  9. printf("创建父子进程失败!");
  10. } else if (fpid == 0) {
  11. printf("子进程ID:%d\n", getpid());
  12. count++;
  13. a = 0;
  14. } else {
  15. printf("父进程ID:%d\n", getpid());
  16. count=10;
  17. a = 1;
  18. }
  19. printf("count=%d\n", count);
  20. printf("a=%d\n", a);
  21. waitpid(fpid, NULL, 0);
  22. return 0;
  23. }
  24. ***************************************************************
  25. /home/wangjing/CLionProjects/untitled/cmake-build-debug/untitled
  26. 父进程ID15229
  27. count=10
  28. a=1
  29. 子进程ID15230
  30. count=1
  31. a=0
  32. Process finished with exit code 0

通过打印的结果,可以发现一些重要信息:

所以说:

1、fork之后,会有两个进程,fork出了一个子进程
2、fork调用完成后,我们的main函数接下来要执行的代码,已经处于了两个不同的进程了,这两个进程都会继续执行剩下的代码,而且不同进程fork的返回值也不一样。
2、两个进程代码是同一份,但是数据却不是同一份

接下来,我们来解释为什么会共享代码?

进程在内存里有三部分的数据——代码段、堆栈段和数据段。这三个部分是构成一个完整的执行序列的必要的部分。

  1. int a;
  2. void main()
  3. {
  4. int b;
  5. int c=func();
  6. }
  7. int func()
  8. {
  9. int d;
  10. return 0;
  11. }

上面这个例子里面,变量b,c,d都是会存放在堆栈段里面,而a则会存放在数据段里

fork()总结:

  • fork函数执行一次,返回两次
  • fork函数之后的代码,子进程和父进程会同时执行,理解为从fork之后,子进程和父进程运行的是同一个程序
  • fork出来的子进程和父进程,共用代码段,但是会拥有各自的数据段和堆栈段

App进程

我们前面说过,pid==0(即运行在子进程)继续开始执行handleChildProc()方法,所以我们从它开始。

  1. ZygoteConnection.handleChildProc()
  2. |
  3. RuntimeInit.zygoteInit()
  4. |
  5. RuntimeInit.commonInit()
  6. |
  7. RuntimeInit.nativeZygoteInit()
  8. |
  9. RuntimeInit.applicationInit()
  10. |
  11. RuntimeInit.invokeStaticMain()
  12. |
  13. ZygoteInit.MethodAndArgsCaller()
  14. |
  15. MethodAndArgsCaller.run()

RuntimeInit.commonInit()

  1. private 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. }

RuntimeInit.nativeZygoteInit()

native方法

RuntimeInit.applicationInit()

  1. private 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()

  1. private 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方法

上面我们说过:

  1. public 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()

  1. public 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进程

  1. ActivityThread.main()
  2. |
  3. ActivityThread.attach()
  4. |
  5. ActivityManagerProxy.attachApplication()
  6. |
  7. ActivityManagerNative.onTransact()
  8. |
  9. ActivityManagerService.attachApplication()
  10. |
  11. ActivityManagerService.attachApplicationLocked()
  12. |
  13. ApplicationThreadNative.ApplicationThreadProxy.bindApplication()
  14. |
  15. ApplicationThreadNative.onTransact()
  16. |
  17. ActivityThread.ApplicationThread.bindApplication()
  18. |
  19. ActivityThread.sendMessage()
  20. |
  21. ActivityThread.H.sendMessage()
  22. |
  23. ActivityThread.H.handleMessage()
  24. |
  25. ActivityThread.handleBindApplication()

ActivityThread.main()

  1. public 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

  1. handleBindApplication(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. }
  16. LoadedApk类:
  17. public 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. }
  29. Instrumentation类:
  30. public Application newApplication(ClassLoader cl, String className, Context context) {
  31. return newApplication(cl.loadClass(className), context);
  32. }
  33. Instrumentation类:
  34. static 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。
  43. final void attach(Context context) {
  44. mBase = base;
  45. mLoadedApk = ContextImpl.getImpl(context).mPackageInfo;
  46. }

可以看出来,Instrumentation和Application,都是反射调用的:

  1. //初始化mInstrumentation
  2. if(data.mInstrumentation!=null) {
  3. mInstrumentation = (Instrumentation) cl.loadClass(data.instrumentationName.getClassName()).newInstance();
  4. }else {
  5. mInstrumentation = new Instrumentation();
  6. }
  7. //实例化Application
  8. Application app = (Application)clazz.newInstance();

Application创建完成之后,就会调用onCreate():

  1. //调用Application的onCreate()方法。
  2. mInstrumentation.callApplicationOnCreate(app);

Activity启动

  1. ActivityThread.main()
  2. |
  3. ActivityThread.attach()
  4. |
  5. ActivityManagerProxy.attachApplication()
  6. |
  7. ActivityManagerNative.onTransact()
  8. |
  9. ActivityManagerService.attachApplication()
  10. |
  11. ActivityManagerService.attachApplicationLocked()
  12. |
  13. ActivityStackSupervisor.attachApplicationLocked()
  14. |
  15. ActivityStackSupervisor.realStartActivityLocked()
  16. |
  17. ClientLifecycleManager.scheduleTransaction()
  18. |
  19. ClientTransaction.schedule()
  20. |
  21. ApplicationThreadNative.ApplicationThreadProxy.scheduleTransaction()
  22. |
  23. ApplicationThreadNative.onTransact()
  24. |
  25. ActivityThread.ApplicationThread.scheduleTransaction()
  26. |
  27. ActivityThread.scheduleTransaction()
  28. |
  29. ClientTransactionHandler.scheduleTransaction()
  30. |
  31. ActivityThread.H.sendMessage(EXECUTE_TRANSACTION)
  32. |
  33. ActivityThread.H.handleMessage()
  34. |
  35. TransactionExecutor.execute()
  36. |
  37. LaunchActivityItem.execute()
  38. |
  39. ActivityThread.handleLaunchActivity()
  40. |
  41. ActivityThread.performLaunchActivity()

在ActivityManagerService.attachApplicationLocked()不仅仅会执行ApplicationThreadNative.ApplicationThreadProxy.bindApplication(),还会执行启动Activity的流程。

小结

参考

https://www.jianshu.com/p/d6562ac93767
https://zhuanlan.zhihu.com/p/433901409
https://juejin.cn/post/6844904116561379341
Android-7-1-2-Android-N-Activity启动流程分析
一篇文章看明白 Android 从点击应用图标到界面显示的过程
Android进程启动流程(App启动)
Android 应用点击图标到Activity界面显示的过程分析

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注