面试进阶之Activity启动过程

二叶草 2020年2月14日20:01:40函数代码评论阅读模式

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),下图描述了它们的关系:

面试进阶之Activity启动过程

进程的创建

理解Android进程创建流程

面试进阶之Activity启动过程

图解:

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进程

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

面试进阶之Activity启动过程

 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}
  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>
 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日内与变化吧联系。

  • 赞助本站
  • 微信扫一扫
  • weinxin
  • 加入Q群
  • QQ扫一扫
  • weinxin
二叶草
Go语言中的常量 函数代码

Go语言中的常量

1 概述 常量,一经定义不可更改的量。功能角度看,当出现不需要被更改的数据时,应该使用常量进行存储,例如圆周率。从语法的角度看,使用常量可以保证数据,在整个运行期间内,不会被更改。例如当前处理器的架构...
Go语言的接口 函数代码

Go语言的接口

Go语言-接口 在Go语言中,一个接口类型总是代表着某一种类型(即所有实现它的类型)的行为。一个接口类型的声明通常会包含关键字type、类型名称、关键字interface以及由花括号包裹的若干方法声明...
Go语言支持的正则语法 函数代码

Go语言支持的正则语法

1 字符 语法 说明 . 任意字符,在单行模式(s标志)下,也可以匹配换行 字符类 否定字符类 d Perl 字符类 D 否定 Perl 字符类 ASCII 字符类 否定 ASCII 字符类 pN U...
Go语言的包管理 函数代码

Go语言的包管理

1 概述 Go 语言的源码复用建立在包(package)基础之上。包通过 package, import, GOPATH 操作完成。 2 main包 Go 语言的入口 main() 函数所在的包(pa...

发表评论