美文网首页
从startActivity一步步到穿越进程壁垒

从startActivity一步步到穿越进程壁垒

作者: jtsky | 来源:发表于2017-09-29 18:01 被阅读160次

起源

身为一名Android程序猿,我们每天都在调用StartActivity来启动另一个页面,可是在调用了成百上千次之后,我们往往会疑惑在执行这行代码的时候,背后到底隐藏着什么原理。是的,我曾不止一次的怀疑过,可是却始终鼓不起勇气去揭开它背后那神秘的面纱。今天,我终于决定硬着头皮走进这超长的调用链,正所谓不成功便成仁,男人就要对自己狠一点。好了,废话不多说,直接开始。(下面有些图来自网络,因为我们往往都是站在巨人得到肩膀上)

开始

Activity#startActivity

  @Override
    public void startActivity(Intent intent, @Nullable Bundle options) {
        if (options != null) {
            startActivityForResult(intent, -1, options);
        } else {
            // Note we want to go through this call for compatibility with
            // applications that may have overridden the method.
            startActivityForResult(intent, -1);
        }
    }

我们都知道加入类中存在多个相同名字的函数时(java重载),最终肯定都会调用到参数最多的那个函数,所以我们直接查看startActivityForResult(intent, -1, options),并且会省略掉许多无关的代码,下面同理,不在强调。
Activity#startActivityForResult

    public void startActivityForResult(Intent intent, int requestCode, @Nullable Bundle options) {
        if (mParent == null) {
    //mMainThread.getApplicationThread()得到ApplicationThread 是一个Binder
            Instrumentation.ActivityResult ar =
                mInstrumentation.execStartActivity(
                    this, mMainThread.getApplicationThread(), mToken, this,
                    intent, requestCode, options);
            if (ar != null) {
                mMainThread.sendActivityResult(
                    mToken, mEmbeddedID, requestCode, ar.getResultCode(),
                    ar.getResultData());
            }else{
                ……
          }
        } 
    }

我们看到代码执行了mInstrumentation.execStartActivity,那mInstrumentation是在什么时候被初始化得到呢?通过查找我们发现以下代码
Activity#attach

final void attach(Context context, ActivityThread aThread,
            Instrumentation instr, IBinder token, int ident,
            Application application, Intent intent, ActivityInfo info,
            CharSequence title, Activity parent, String id,
            NonConfigurationInstances lastNonConfigurationInstances,
            Configuration config, String referrer, IVoiceInteractor voiceInteractor,
            Window window) {
        //注意这行代码 我们知道startActivity可以在任何Context中调用 下文会分析
        attachBaseContext(context);
           ……
        mUiThread = Thread.currentThread();
        mMainThread = aThread;
        mInstrumentation = instr;
        mToken = token;
        mIdent = ident;
        mApplication = application;
        mIntent = intent;
        mReferrer = referrer;
        mComponent = intent.getComponent();
        mActivityInfo = info;
        mTitle = title;
        mParent = parent;
        mEmbeddedID = id;
        mLastNonConfigurationInstances = lastNonConfigurationInstances;
       ……
    

那这个instr到底是什么呢,我们继续查找在ActivityThread中发现了一下代码
ActivityThread#performLaunchActivity

 private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
                       ……
        try {
            Application app = r.packageInfo.makeApplication(false, mInstrumentation);
            if (activity != null) {
                //注意这行代码,他其实就是ContextWrapper中的mBase,下面会分析
                Context appContext = createBaseContextForActivity(r, activity);
                activity.attach(appContext, this, getInstrumentation(), r.token,
                        r.ident, app, r.intent, r.activityInfo, title, r.parent,
                        r.embeddedID, r.lastNonConfigurationInstances, config,
                        r.referrer, r.voiceInteractor, window);
                    ……

        } 
        return activity;
    }
 }

可以看到instr是由getInstrumentation()传入的,而真正的Instrumentation是在ActivityThread中直接new出来的,看一下代码:
ActivityThread#attach

 private void attach(boolean system) {
       try {
                mInstrumentation = new Instrumentation();
                ContextImpl context = ContextImpl.createAppContext(
                        this, getSystemContext().mPackageInfo);
                mInitialApplication = context.mPackageInfo.makeApplication(true, null);
                mInitialApplication.onCreate();
            } catch (Exception e) {
                throw new RuntimeException(
                        "Unable to instantiate Application():" + e.toString(), e);
            }
    }

好了Instrumentation找到了,没有继承,也没有子类什么,那我们直接去看他的execStartActivity()方法
Instrumentation#execStartActivity

public ActivityResult execStartActivity(
            Context who, IBinder contextThread, IBinder token, Activity target,
            Intent intent, int requestCode, Bundle options) {
              ……
            int result = ActivityManagerNative.getDefault()
                .startActivity(whoThread, who.getBasePackageName(), intent,
                        intent.resolveTypeIfNeeded(who.getContentResolver()),
                        token, target != null ? target.mEmbeddedID : null,
                        requestCode, 0, null, options);
           ……
}

可以看到 我们找到了最终的调用点ActivityManagerNative.getDefault().startActivity,至于ActivityManagerNative是什么,我们先放放等下再分析。还记得我在上面提到过,我们其实可以在任何的Contex中调用startActivity,那如果不是在activity中调用,那他的调用流程是什么样的呢?我们以Service为例看下。经过搜索我们发现Service中并没有StartActivity方法,那我们就在它的父类ContextWrapper中查找,发现以下代码:
ContextWrapper#startActivity

    @Override
    public void startActivity(Intent intent) {
        mBase.startActivity(intent);
    }

protected void attachBaseContext(Context base) {
        if (mBase != null) {
            throw new IllegalStateException("Base context already set");
        }
        mBase = base;
    }

直接通过mBase调用,而mBase 是通过attachBaseContext直接赋值的,那这个mBase到底是个什么鬼,还记得我在Activity中提到的attachBaseContext吗,没错调用的就是这里,然后 Activity#attach的调用链已经分析过了,在ActivityThread#performLaunchActivity中被调用,大家可以去看上面的代码。
ActivityThread#createBaseContextForActivity

private Context createBaseContextForActivity(ActivityClientRecord r, final Activity activity) {
         ……
        ContextImpl appContext = ContextImpl.createActivityContext(
                this, r.packageInfo, r.token, displayId, r.overrideConfig);
        appContext.setOuterContext(activity);
        Context baseContext = appContext;
        ……
        return baseContext;
    }

原来是通过ContextImpl#createActivityContext得到的,废话不多说进去看看
ContextImpl#createActivityContext

static ContextImpl createActivityContext(ActivityThread mainThread,
            LoadedApk packageInfo, IBinder activityToken, int displayId,
            Configuration overrideConfiguration) {
        if (packageInfo == null) throw new IllegalArgumentException("packageInfo");
        return new ContextImpl(null, mainThread, packageInfo, activityToken, null, 0,
                null, overrideConfiguration, displayId);
    }

直接new了他自己,真实简单粗暴,不过我喜欢,哈哈。所以我们直接去看他的StartActivity
ContextImpl#startActivity

@Override
    public void startActivity(Intent intent, Bundle options) {
        warnIfCallingFromSystemProcess();
       // Calling start activity from outside an activity without FLAG_ACTIVITY_NEW_TASK is
        // generally not allowed, except if the caller specifies the task id the activity should
        // be launched in.
        if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0
                && options != null && ActivityOptions.fromBundle(options).getLaunchTaskId() == -1) {
            throw new AndroidRuntimeException(
                    "Calling startActivity() from outside of an Activity "
                    + " context requires the FLAG_ACTIVITY_NEW_TASK flag."
                    + " Is this really what you want?");
        }
        mMainThread.getInstrumentation().execStartActivity(
                getOuterContext(), mMainThread.getApplicationThread(), null,
                (Activity) null, intent, -1, options);
       ……
    }

看到了吗 看到了吗 看到了吗,重要的话说三遍,跟上面连起来了,mMainThread其实就是ActivityThread,原来哪怕你的调用栈再深,最终返回的还是同一个Instrumentation,真实666啊。还有一点,我们记得如果是在除Activity中启动另一个Activity是需要动态设置启动模式为FLAG_ACTIVITY_NEW_TASK的,其实就是在这里做了判断。
好了想到这,我们来简单的总结下:
我们先来看看Context家族,放一张网上的图片,方便大家记忆:

image.png

从名字我们可以看出ContextWrapper是Context的包装类,而ContexImpl才是Context的实现类,只要跟Context有关的调用,最终肯定会进到ContexImpl中。

----------------------------------------我的是分割线-----------------------------------------------------

OK,我们继续咱的分析,上面咱们调用到了ActivityManagerNative.getDefault().startActivity。所以咱们首先得了解ActivityManagerNative是什么,其实这里已经开始涉及到Bindle了,还有一丢丢的小兴奋呢,废话不多说,先上图,大致了解一下Bindle相关类。

image.png

这是关于framework层的Binder架构图

image.png

这是我自己整理的关于应用层Activity模块的的Binder架构图

从上面2张图我们可以看出架构是一一对应的,建议大家对照着看,从图中我们可以看到ActivityManagerNative是Binder的子类,那Binder到底是什么,其实要说明白这个问题,其实很困难,因为它太复杂了,在这里我给介绍网上一个叫gityuan的大神,他分析的很透彻,强烈建议大家先看完他的博文在回来继续阅读,下面放上链接:彻底理解Android Binder通信架构

好了,我们继续我们的博文

Binder家族

相信大家已经看过大神的博文,但是我还是想把相关的概念再理一遍,对于这么复杂的框架,重复一遍加深记忆应该是没错的,另一方面也是为了自己博文的连贯性,方便那些不想跳转链接的朋友,请大家见谅,还有一点,大神分析的调用栈是startService(),而我是故意选择startActivity()的,因为只有自己跟一遍代码,才能真正掌握一个知识点,好的我们开始。
以下的概念和图直接摘录大神博文,就当做增加了一个推广渠道吧
我们先对比下TCP/IP的五层通信体系结构和Binder的架构:

image.png image.png

怎么样,是不是很像,每一层负责自己的业务逻辑代码,然后层与层之间定义好接口,方便上一层调用。 这里盗用一下大神的图

image.png

大家把startService()换成startActivity()其实是一样的(请大家原谅我的厚脸皮)。
其中AMP作为Binder的客户端,运行在各个app所在进程, AMN(或AMS)运行在系统进程system_server。

Binder IPC原理

image.png

上面这张图是Binder进程间调用架构图
可以看出无论是注册服务和获取服务的过程都需要ServiceManager,需要注意的是此处的Service Manager是指Native层的ServiceManager(C++),并非指framework层的ServiceManager(Java)。ServiceManager是整个Binder通信机制的大管家,是Android进程间通信机制Binder的守护进程,Client端和Server端通信时都需要先获取Service Manager接口,才能开始通信服务, 当然查找到目标信息可以缓存起来则不需要每次都向ServiceManager请求。

图中Client/Server/ServiceManage之间的相互通信都是基于Binder机制。既然基于Binder机制通信,那么同样也是C/S架构,则图中的3大步骤都有相应的Client端与Server端。

  1. 注册服务:首先AMS注册到ServiceManager。该过程:AMS所在进程(system_server)是客户端,ServiceManager是服务端。
  2. 获取服务:Client进程使用AMS前,须先向ServiceManager中获取AMS的代理类AMP。该过程:AMP所在进程(app process)是客户端,ServiceManager是服务端。
  3. 使用服务: app进程根据得到的代理类AMP,便可以直接与AMS所在进程交互。该过程:AMP所在进程(app process)是客户端,AMS所在进程(system_server)是服务端。

图中的Client,Server,Service Manager之间交互都是虚线表示,是由于它们彼此之间不是直接交互的,而是都通过与Binder Driver进行交互的,从而实现IPC通信方式。其中Binder驱动位于内核空间,Client,Server,Service Manager位于用户空间。Binder驱动和Service Manager可以看做是Android平台的基础架构,而Client和Server是Android的应用层.
好了,概念的东西讲完了,继续我们的代码跟踪(以下博文为原创):
ActivityManagerNative#getDefault()

static public IActivityManager getDefault() {
        return gDefault.get();
    }

private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
        protected IActivityManager create() {
            IBinder b = ServiceManager.getService("activity");
            if (false) {
                Log.v("ActivityManager", "default service binder = " + b);
            }
            IActivityManager am = asInterface(b);
            if (false) {
                Log.v("ActivityManager", "default service = " + am);
            }
            return am;
        }
    };
}

ServiceManager#getService

public static IBinder getService(String name) {
        try {
            IBinder service = sCache.get(name);
            if (service != null) {
                return service;
            } else {
                return getIServiceManager().getService(name);
            }
        } catch (RemoteException e) {
            Log.e(TAG, "error in getService", e);
        }
        return null;
    }

注意看面的代码ServiceManager.getService("activity")得到的是IBinder的子类,但是具体是什么呢?这里好像看不太出来,想猜一下吧,是ActivityService吗?经过查找并没有这个类,好吧我们先把这个放一放,看来遇到了点麻烦。没事,既然不知道是什么,那我就直接调试,请看下图

image.png

很明显ActivityManagerNative#getDefault()返回的是ActivityManagerProxy,同时我们还知道了mRemote是BinderProxy。这里推荐大家看下gityuan的另一篇文章:
Binder系列7—framework层分析,里面有解释。这里我总结一下getIServiceManager().getService(name)其实调用的是ServiceManagerProxy#getService

public IBinder getService(String name) throws RemoteException {
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
        data.writeInterfaceToken(IServiceManager.descriptor);
        data.writeString(name);
        //mRemote为BinderProxy
        mRemote.transact(GET_SERVICE_TRANSACTION, data, reply, 0);
        //从reply里面解析出获取的IBinder对象
        IBinder binder = reply.readStrongBinder();
        reply.recycle();
        data.recycle();
        return binder;
    }

BinderProxy#transact

 public boolean transact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
        Binder.checkParcel(this, code, data, "Unreasonably large binder buffer");
        return transactNative(code, data, reply, flags);
    }

public native boolean transactNative(int code, Parcel data, Parcel reply,
            int flags) throws RemoteException;

到掉到C++代码了,我们就继续往下分析了,大家该兴趣的话可以去看Binder系列7—framework层分析,这里我直接说结论吧:
通过getService()最终获取到的指向目标Binder服务端的代理对象BinderProxy。
getService的核心过程:

public static IBinder getService(String name) {
    ...
    Parcel reply = Parcel.obtain(); //此处还需要将java层的Parcel转为Native层的Parcel
    BpBinder::transact(GET_SERVICE_TRANSACTION, *data, reply, 0);  //与Binder驱动交互
    IBinder binder = javaObjectForIBinder(env, new BpBinder(handle));
    ...
}

好了,我们继续分析AMP(ActivityManagerProxy)的创建
ActivityManagerNative#asInterface

static public IActivityManager asInterface(IBinder obj) {
        if (obj == null) {
            return null;
        }
        IActivityManager in =
            (IActivityManager)obj.queryLocalInterface(descriptor);
        if (in != null) {
            return in;
        }

        return new ActivityManagerProxy(obj);
    }

此时obj为BinderProxy对象,queryLocalInterface的实现在BinderProxy中,我们可以看下代码

public class Binder implements IBinder {
    //对于Binder对象的调用,则返回值不为空
    public IInterface queryLocalInterface(String descriptor) {
        //mDescriptor的初始化在attachInterface()过程中赋值
        if (mDescriptor.equals(descriptor)) {
            return mOwner;
        }
        return null;
    }
}

final class BinderProxy implements IBinder {
    //BinderProxy对象的调用, 则返回值为空
    public IInterface queryLocalInterface(String descriptor) {
        return null;
    }
}

可以看到这里返回的是null,好了,我们先总结一下:
对于Binder IPC的过程中, 同一个进程中Binder调用asInterface()方法返回的便是本地的Binder对象;对于不同进程的BinderProxy调用asInterface()则返回空。
继续看代码
ActivityManagerProxy#ActivityManagerProxy

public ActivityManagerProxy(IBinder remote)
    {
        mRemote = remote;
    }

可知mRemote便是指向AMS服务的BinderProxy对象,搞了半天,我们回到startActivity调用链,说实话真的有点累啊。
ActivityManagerNative.getDefault().startActivity就相当于是
ActivityManagerProxy#startActivity

  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 {
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
        data.writeInterfaceToken(IActivityManager.descriptor);
        data.writeStrongBinder(caller != null ? caller.asBinder() : null);
        data.writeString(callingPackage);
        intent.writeToParcel(data, 0);
        data.writeString(resolvedType);
        data.writeStrongBinder(resultTo);
        data.writeString(resultWho);
        data.writeInt(requestCode);
        data.writeInt(startFlags);
        if (profilerInfo != null) {
            data.writeInt(1);
            profilerInfo.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
        } else {
            data.writeInt(0);
        }
        if (options != null) {
            data.writeInt(1);
            options.writeToParcel(data, 0);
        } else {
            data.writeInt(0);
        }
        //其实重点是这行的代码
        mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0);
        reply.readException();
        int result = reply.readInt();
        reply.recycle();
        data.recycle();
        return result;
    }

BinderProxy#transact

final class BinderProxy implements IBinder {
    public boolean transact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
        //用于检测Parcel大小是否大于800k
        Binder.checkParcel(this, code, data, "Unreasonably large binder buffer");
        return transactNative(code, data, reply, flags);
    }
}

又是C++本地方法,直接上链接彻底理解Android Binder通信架构2.5小节开始
我这里自己说结论吧,其实在transactNative的本地方法调用栈中,经过一系列的调用最终会进入
Binder#execTransact

private boolean execTransact(int code, long dataObj, long replyObj,
        int flags) {
    Parcel data = Parcel.obtain(dataObj);
    Parcel reply = Parcel.obtain(replyObj);

    boolean res;
    try {
        // 调用子类AMN.onTransact方法
        res = onTransact(code, data, reply, flags);
    } catch (RemoteException e) {
        if ((flags & FLAG_ONEWAY) != 0) {
            ...
        } else {
            //非oneway的方式,则会将异常写回reply
            reply.setDataPosition(0);
            reply.writeException(e);
        }
        res = true;
    } catch (RuntimeException e) {
        if ((flags & FLAG_ONEWAY) != 0) {
            ...
        } else {
            reply.setDataPosition(0);
            reply.writeException(e);
        }
        res = true;
    } catch (OutOfMemoryError e) {
        RuntimeException re = new RuntimeException("Out of memory", e);
        reply.setDataPosition(0);
        reply.writeException(re);
        res = true;
    }
    reply.recycle();
    data.recycle();
    return res;
}

好了, 上面的代码调用到了之类的onTransact方法,即:
ActivityManagerNative#onTransact

  @Override
    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
            throws RemoteException {
  switch (code) {
      case START_ACTIVITY_TRANSACTION:
      {
     data.enforceInterface(IActivityManager.descriptor);
            IBinder b = data.readStrongBinder();
            IApplicationThread app = ApplicationThreadNative.asInterface(b);
            String callingPackage = data.readString();
            Intent intent = Intent.CREATOR.createFromParcel(data);
            String resolvedType = data.readString();
            IBinder resultTo = data.readStrongBinder();
            String resultWho = data.readString();
            int requestCode = data.readInt();
            int startFlags = data.readInt();
            ProfilerInfo profilerInfo = data.readInt() != 0
                    ? ProfilerInfo.CREATOR.createFromParcel(data) : null;
            Bundle options = data.readInt() != 0
                    ? Bundle.CREATOR.createFromParcel(data) : null;
             //调用ActivityManagerService的startActivity()方法
            int result = startActivity(app, callingPackage, intent, resolvedType,
                    resultTo, resultWho, requestCode, startFlags, profilerInfo, options);
            reply.writeNoException();
            reply.writeInt(result);
            return true;
      }
  }
}

上面说到mRemote是指向AMS服务的BinderProxy对象,所以此次的startActivity调用的就是ActivityManagerService#startActivity

@Override
    public final int startActivity(IApplicationThread caller, String callingPackage,
            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
            resultWho, requestCode, startFlags, profilerInfo, options,
            UserHandle.getCallingUserId());
    }

    @Override
    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
        enforceNotIsolatedCaller("startActivity");
        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
                false, ALLOW_FULL_ONLY, "startActivity", null);
        // TODO: Switch to user app stacks here.
        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
                profilerInfo, null, null, options, false, userId, null, null);
    }

mStackSupervisor又是什么鬼,我们直接进去看看吧

当程序运行到这里时, ASS.startActivityMayWait的各个参数取值如下:
caller = ApplicationThreadProxy, 用于跟调用者进程ApplicationThread进行通信的binder代理类.
callingUid = -1;
callingPackage = ContextImpl.getBasePackageName(),获取调用者Activity所在包名
intent: 这是启动Activity时传递过来的参数;
resolvedType = intent.resolveTypeIfNeeded
voiceSession = null;
voiceInteractor = null;
resultTo = Activity.mToken, 其中Activity是指调用者所在Activity, mToken对象保存自己所处的ActivityRecord信息
resultWho = Activity.mEmbeddedID, 其中Activity是指调用者所在Activity
requestCode = -1;
startFlags = 0;
profilerInfo = null;
outResult = null;
config = null;
options = null;
ignoreTargetSecurity = false;
userId = AMS.handleIncomingUser, 当调用者userId跟当前处于同一个userId,则直接返回该userId;当不相等时则根据调用者userId来决定是否需要将callingUserId转换为mCurrentUserId.
iContainer = null;
inTask = null;

参数真是多啊,心好累,但是我不能放弃,直接看源码
由于下面的代码过长我只贴重要的方法,详细请见startActivity启动过程分析2.7小节开始
ActivityStackSupervisor#startActivityMayWait

final int startActivityMayWait(IApplicationThread caller, int callingUid,
        String callingPackage, Intent intent, String resolvedType,
        IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
        IBinder resultTo, String resultWho, int requestCode, int startFlags,
        ProfilerInfo profilerInfo, WaitResult outResult, Configuration config,
        Bundle options, boolean ignoreTargetSecurity, int userId,
        IActivityContainer iContainer, TaskRecord inTask) {
    ...
    boolean componentSpecified = intent.getComponent() != null;
    //创建新的Intent对象,即便intent被修改也不受影响
    intent = new Intent(intent);

    //收集Intent所指向的Activity信息, 当存在多个可供选择的Activity,则直接向用户弹出resolveActivity 
    ActivityInfo aInfo = resolveActivity(intent, resolvedType, startFlags, profilerInfo, userId);
    ……
   int res = startActivityLocked(caller, intent, resolvedType, aInfo,
                voiceSession, voiceInteractor, resultTo, resultWho,
                requestCode, callingPid, callingUid, callingPackage,
                realCallingPid, realCallingUid, startFlags, options, ignoreTargetSecurity,
                componentSpecified, null, container, inTask);

        return res;
    }
}

ASS.resolveActivity()方法的核心功能是找到相应的Activity组件,并保存到intent对象
ActivityStackSupervisor#startActivityLocked

final int startActivityLocked(IApplicationThread caller,
        Intent intent, String resolvedType, ActivityInfo aInfo,
        IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
        IBinder resultTo, String resultWho, int requestCode,
        int callingPid, int callingUid, String callingPackage,
        int realCallingPid, int realCallingUid, int startFlags, Bundle options,
        boolean ignoreTargetSecurity, boolean componentSpecified, ActivityRecord[] outActivity,
        ActivityContainer container, TaskRecord inTask) {
          ……
           final int launchFlags = intent.getFlags();

    if ((launchFlags & Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0 && sourceRecord != null) {
        ... // activity执行结果的返回由源Activity转换到新Activity, 不需要返回结果则不会进入该分支
    }

    if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) {
        //从Intent中无法找到相应的Component
        err = ActivityManager.START_INTENT_NOT_RESOLVED;
    }

    if (err == ActivityManager.START_SUCCESS && aInfo == null) {
        //从Intent中无法找到相应的ActivityInfo
        err = ActivityManager.START_INTENT_NOT_RESOLVED;
    }
      ……
   // 创建Activity记录对象
    ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage,
            intent, resolvedType, aInfo, mService.mConfiguration, resultRecord, resultWho,
            requestCode, componentSpecified, voiceSession != null, this, container, options);
     ……
    if (voiceSession == null && (stack.mResumedActivity == null
            || stack.mResumedActivity.info.applicationInfo.uid != callingUid)) {
        // 前台stack还没有resume状态的Activity时, 则检查app切换是否允许 [见流程2.8.1]
        if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid,
                realCallingPid, realCallingUid, "Activity start")) {
            PendingActivityLaunch pal =
                    new PendingActivityLaunch(r, sourceRecord, startFlags, stack);
            // 当不允许切换,则把要启动的Activity添加到mPendingActivityLaunches对象, 并且直接返回.
            mPendingActivityLaunches.add(pal);
            ActivityOptions.abort(options);
            return ActivityManager.START_SWITCHES_CANCELED;
        }
    }

    if (mService.mDidAppSwitch) {
        //从上次禁止app切换以来,这是第二次允许app切换,因此将允许切换时间设置为0,则表示可以任意切换app
        mService.mAppSwitchesAllowedTime = 0;
    } else {
        mService.mDidAppSwitch = true;
    }

    //处理 pendind Activity的启动, 这些Activity是由于app switch禁用从而被hold的等待启动activity 
    doPendingActivityLaunchesLocked(false);

    err = startActivityUncheckedLocked(r, sourceRecord, voiceSession, voiceInteractor,
            startFlags, true, options, inTask);

    if (err < 0) {
        notifyActivityDrawnForKeyguard();
    }
      return err;
}

其中有两个返回值代表启动Activity失败:

  • START_INTENT_NOT_RESOLVED: 从Intent中无法找到相应的Component或者ActivityInfo
  • START_NOT_CURRENT_USER_ACTIVITY:该Activity对当前用户不可见
    AMS#doPendingActivityLaunchesLocked
final void doPendingActivityLaunchesLocked(boolean doResume) {
    while (!mPendingActivityLaunches.isEmpty()) {
        PendingActivityLaunch pal = mPendingActivityLaunches.remove(0);
        try {
            startActivityUncheckedLocked(pal.r, pal.sourceRecord, null, null, pal.startFlags,
                                         doResume && mPendingActivityLaunches.isEmpty(), null, null);
        } catch (Exception e) {
            ...
        }
    }
}

startActivityUncheckedLocked方法的代码相当的长足足有差不多快700行,这里就补贴代码,其实他的主要重要就是找到或创建新的Activit所属于的Task对象,这中间有各种判断条件,一行一行看会看晕掉,在检查完成会后会调用targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options);targetStack是ActivityStack对象,从名字就可以看出,这是一个Activity管理栈。
再继续下面的代码之前,我们先来看下activity的启动模式

Launch Mode(摘录自博客startActivity启动过程分析)

先来说说在ActivityInfo.java中定义了4类Launch Mode:

  • LAUNCH_MULTIPLE(standard):最常见的情形,每次启动Activity都是创建新的Activity;
  • LAUNCH_SINGLE_TOP: 当Task顶部存在同一个Activity则不再重新创建;其余情况同上;
  • LAUNCH_SINGLE_TASK:当Task栈存在同一个Activity(不在task顶部),则不重新创建,而
    移除该Activity上面其他的Activity;其余情况同上;
  • LAUNCH_SINGLE_INSTANCE:每个Task只有一个Activity.

再来说说几个常见的flag含义:

  • FLAG_ACTIVITY_NEW_TASK:将Activity放入一个新启动的Task;
  • FLAG_ACTIVITY_CLEAR_TASK:启动Activity时,将目标Activity关联的Task清除,再启动新Task,将该Activity放入该Task。该flags跟FLAG_ACTIVITY_NEW_TASK配合使用。
  • FLAG_ACTIVITY_CLEAR_TOP:启动非栈顶Activity时,先清除该Activity之上的Activity。例如Task已有A、B、C3个Activity,启动A,则清除B,C。类似于SingleTop。

最后再说说:设置FLAG_ACTIVITY_NEW_TASK的几个情况:

  • 调用者并不是Activity context;
  • 调用者activity带有single instance;
  • 目标activity带有single instance或者single task;
  • 调用者处于finishing状态;

ActivityStack#startActivityLocked

final void startActivityLocked(ActivityRecord r, boolean newTask,
        boolean doResume, boolean keepCurTransition, Bundle options) {
 if (!r.mLaunchTaskBehind && (taskForIdLocked(taskId) == null || newTask)) {
        //task中的上一个activity已被移除,或者ams重用该task,则将该task移到顶部
        insertTaskAtTop(rTask, r);
        mWindowManager.moveTaskToTop(taskId);
    }
  ……
 if (doResume) {
       //重点关注这行代码
        mStackSupervisor.resumeTopActivitiesLocked(this, r, options);
    }

}

mStackSupervisor是ActivityStackSupervisor的对象
ActivityStackSupervisor#resumeTopActivitiesLocked

boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target,
        Bundle targetOptions) {
    if (targetStack == null) {
        targetStack = mFocusedStack;
    }

    boolean result = false;
    if (isFrontStack(targetStack)) {
       //重点关注这行代码
        result = targetStack.resumeTopActivityLocked(target, targetOptions);
    }

    for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
        final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
        for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
            final ActivityStack stack = stacks.get(stackNdx);
            if (stack == targetStack) {
                //上面刚已启动
                continue;
            }
            if (isFrontStack(stack)) {
                stack.resumeTopActivityLocked(null);
            }
        }
    }
    return result;
}

又回到ActivityStack了
ActivityStack#resumeTopActivityLocked

final boolean resumeTopActivityLocked(ActivityRecord prev, Bundle options) {
    if (mStackSupervisor.inResumeTopActivity) {
        return false; //防止递归启动
    }

    boolean result = false;
    try {
        mStackSupervisor.inResumeTopActivity = true;
        if (mService.mLockScreenShown == ActivityManagerService.LOCK_SCREEN_LEAVING) {
            mService.mLockScreenShown = ActivityManagerService.LOCK_SCREEN_HIDDEN;
            mService.updateSleepIfNeededLocked();
        }
        //重点关注这行代码
        result = resumeTopActivityInnerLocked(prev, options);
    } finally {
        mStackSupervisor.inResumeTopActivity = false;
    }
    return result;
}

ActivityStack#resumeTopActivityInnerLocked

private boolean resumeTopActivityInnerLocked(ActivityRecord prev, Bundle options) {
        ……
 if (next == null) {
        final String reason = "noMoreActivities";
        if (!mFullscreen) {
            //当该栈没有全屏,则尝试聚焦到下一个可见的stack
            final ActivityStack stack = getNextVisibleStackLocked();
            if (adjustFocusToNextVisibleStackLocked(stack, reason)) {
                return mStackSupervisor.resumeTopActivitiesLocked(stack, prev, null);
            }
        }
        ActivityOptions.abort(options);
        final int returnTaskType = prevTask == null || !prevTask.isOverHomeStack() ?
                HOME_ACTIVITY_TYPE : prevTask.getTaskToReturnTo();
        //启动home桌面activity
        return isOnHomeDisplay() &&
                mStackSupervisor.resumeHomeStackTask(returnTaskType, prev, reason);
    }
        ……
    //需要等待暂停当前activity完成,再resume top activity
    boolean dontWaitForPause = (next.info.flags&ActivityInfo.FLAG_RESUME_WHILE_PAUSING) != 0;
    //暂停其他Activity[见小节2.13.1]
    boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving, true, dontWaitForPause);
    if (mResumedActivity != null) {
        //当前resumd状态activity不为空,则需要先暂停该Activity 注意这行代码
        pausing |= startPausingLocked(userLeaving, false, true, dontWaitForPause);
    }
        ……

  mStackSupervisor.startSpecificActivityLocked(next, true, true);
  return true;
}

主要分支功能:

  • 当找不到需要resume的Activity,则直接回到桌面;
  • 否则,当mResumedActivity不为空,则执行startPausingLocked()暂停该activity;
  • 然后再进入startSpecificActivityLocked环节,接下来从这里继续往下说。

ActivityStackSupervisor#pauseBackStacks

boolean pauseBackStacks(boolean userLeaving, boolean resuming, boolean dontWait) {
    boolean someActivityPaused = false;
    for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
        ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
        for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
            final ActivityStack stack = stacks.get(stackNdx);
            if (!isFrontStack(stack) && stack.mResumedActivity != null) {
                //[见小节2.13.2]
                someActivityPaused |= stack.startPausingLocked(userLeaving, false, resuming,
                        dontWait);
            }
        }
    }
    return someActivityPaused;
}

ActivityStack#startPausingLocked

final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping, boolean resuming,
     boolean dontWait) {
  if (mPausingActivity != null) {
      if (!mService.isSleeping()) {
          completePauseLocked(false);
      }
  }
  ActivityRecord prev = mResumedActivity;
  ...

  if (mActivityContainer.mParentActivity == null) {
      //暂停所有子栈的Activity
      mStackSupervisor.pauseChildStacks(prev, userLeaving, uiSleeping, resuming, dontWait);
  }
  ...
  final ActivityRecord next = mStackSupervisor.topRunningActivityLocked();
  
  if (prev.app != null && prev.app.thread != null) {
      EventLog.writeEvent(EventLogTags.AM_PAUSE_ACTIVITY,
              prev.userId, System.identityHashCode(prev),
              prev.shortComponentName);
      mService.updateUsageStats(prev, false);
      //暂停目标Activity
      prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing,
              userLeaving, prev.configChangeFlags, dontWait);
  }else {
      ...
  }

  if (!uiSleeping && !mService.isSleepingOrShuttingDown()) {
      mStackSupervisor.acquireLaunchWakelock(); //申请wakelock
  }

  if (mPausingActivity != null) {
      if (!uiSleeping) {
          prev.pauseKeyDispatchingLocked();
      } 

      if (dontWait) {
          completePauseLocked(false); 
          return false;
      } else {
          Message msg = mHandler.obtainMessage(PAUSE_TIMEOUT_MSG);
          msg.obj = prev;
          prev.pauseTime = SystemClock.uptimeMillis();
          //500ms后,执行暂停超时的消息
          mHandler.sendMessageDelayed(msg, PAUSE_TIMEOUT);
          return true;
      }

  } else {
      if (!resuming) { //调度暂停失败,则认为已暂停完成,开始执行resume操作
          mStackSupervisor.getFocusedStack().resumeTopActivityLocked(null);
      }
      return false;
  }

ActivityStackSupervisor#startSpecificActivityLocked

void startSpecificActivityLocked(ActivityRecord r,
        boolean andResume, boolean checkConfig) {
    ProcessRecord app = mService.getProcessRecordLocked(r.processName,
            r.info.applicationInfo.uid, true);

    r.task.stack.setLaunchTime(r);

    if (app != null && app.thread != null) {
        try {
            if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0
                    || !"android".equals(r.info.packageName)) {
                app.addPackage(r.info.packageName, r.info.applicationInfo.versionCode,
                        mService.mProcessStats);
            }
            //真正的启动Activity 注意这行
            realStartActivityLocked(r, app, andResume, checkConfig);
            return;
        } catch (RemoteException e) {
            Slog.w(TAG, "Exception when starting activity "
                    + r.intent.getComponent().flattenToShortString(), e);
        }

    }
    //当进程不存在则创建进程
    mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
            "activity", r.intent.getComponent(), false, false, true);
}

ActivityStackSupervisor#realStartActivityLocked

final boolean realStartActivityLocked(ActivityRecord r,
        ProcessRecord app, boolean andResume, boolean checkConfig)
        throws RemoteException {

        //调度启动ticks用以收集应用启动慢的信息
        r.startLaunchTickingLocked();
      //注意这行代码
      app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
                System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration),
                new Configuration(stack.mOverrideConfig), r.compat, r.launchedFromPackage,
                task.voiceInteractor, app.repProcState, r.icicle, r.persistentState, results,
                newIntents, !andResume, mService.isNextTransitionForward(), profilerInfo);

    //更新所有与该Activity具有绑定关系的Service连接
    mService.mServices.updateServiceConnectionActivitiesLocked(r.app);

    return true;

app.thread其实就是ApplicationThreadProxy对象
ApplicationThreadProxy#scheduleLaunchActivity

public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
         ActivityInfo info, Configuration curConfig, Configuration overrideConfig,
         CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor,
         int procState, Bundle state, PersistableBundle persistentState,
         List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents,
         boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) throws RemoteException {
     Parcel data = Parcel.obtain();
     data.writeInterfaceToken(IApplicationThread.descriptor);
     intent.writeToParcel(data, 0);
     data.writeStrongBinder(token);
     data.writeInt(ident);
     info.writeToParcel(data, 0);
     curConfig.writeToParcel(data, 0);
     if (overrideConfig != null) {
         data.writeInt(1);
         overrideConfig.writeToParcel(data, 0);
     } else {
         data.writeInt(0);
     }
     compatInfo.writeToParcel(data, 0);
     data.writeString(referrer);
     data.writeStrongBinder(voiceInteractor != null ? voiceInteractor.asBinder() : null);
     data.writeInt(procState);
     data.writeBundle(state);
     data.writePersistableBundle(persistentState);
     data.writeTypedList(pendingResults);
     data.writeTypedList(pendingNewIntents);
     data.writeInt(notResumed ? 1 : 0);
     data.writeInt(isForward ? 1 : 0);
     if (profilerInfo != null) {
         data.writeInt(1);
         profilerInfo.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
     } else {
         data.writeInt(0);
     }
     //注意这行代码
     mRemote.transact(SCHEDULE_LAUNCH_ACTIVITY_TRANSACTION, data, null,
             IBinder.FLAG_ONEWAY);
     data.recycle();
 }

按照我们上面的分析,这里的mRemote应该的指向ApplicationThread的BinderProxy对象,所以 mRemote.transact(SCHEDULE_LAUNCH_ACTIVITY_TRANSACTION, data, null,
IBinder.FLAG_ONEWAY);会调用到
ApplicationThreadNative#onTransact

 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
            throws RemoteException {
switch (code) {
        case SCHEDULE_LAUNCH_ACTIVITY_TRANSACTION:
        {
            data.enforceInterface(IApplicationThread.descriptor);
            Intent intent = Intent.CREATOR.createFromParcel(data);
            IBinder b = data.readStrongBinder();
            int ident = data.readInt();
            ActivityInfo info = ActivityInfo.CREATOR.createFromParcel(data);
            Configuration curConfig = Configuration.CREATOR.createFromParcel(data);
            Configuration overrideConfig = null;
            if (data.readInt() != 0) {
                overrideConfig = Configuration.CREATOR.createFromParcel(data);
            }
            CompatibilityInfo compatInfo = CompatibilityInfo.CREATOR.createFromParcel(data);
            String referrer = data.readString();
            IVoiceInteractor voiceInteractor = IVoiceInteractor.Stub.asInterface(
                    data.readStrongBinder());
            int procState = data.readInt();
            Bundle state = data.readBundle();
            PersistableBundle persistentState = data.readPersistableBundle();
            List<ResultInfo> ri = data.createTypedArrayList(ResultInfo.CREATOR);
            List<ReferrerIntent> pi = data.createTypedArrayList(ReferrerIntent.CREATOR);
            boolean notResumed = data.readInt() != 0;
            boolean isForward = data.readInt() != 0;
            ProfilerInfo profilerInfo = data.readInt() != 0
                    ? ProfilerInfo.CREATOR.createFromParcel(data) : null;
            //注意这行代码
            scheduleLaunchActivity(intent, b, ident, info, curConfig, overrideConfig, compatInfo,
                    referrer, voiceInteractor, procState, state, persistentState, ri, pi,
                    notResumed, isForward, profilerInfo);
            return true;
       }
}

ApplicationThread#scheduleLaunchActivity

public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
         ActivityInfo info, Configuration curConfig, Configuration overrideConfig,
         CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor,
         int procState, Bundle state, PersistableBundle persistentState,
         List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents,
         boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) {

     updateProcessState(procState, false);

     ActivityClientRecord r = new ActivityClientRecord();

     r.token = token;
     r.ident = ident;
     r.intent = intent;
     r.referrer = referrer;
     r.voiceInteractor = voiceInteractor;
     r.activityInfo = info;
     r.compatInfo = compatInfo;
     r.state = state;
     r.persistentState = persistentState;

     r.pendingResults = pendingResults;
     r.pendingIntents = pendingNewIntents;

     r.startsNotResumed = notResumed;
     r.isForward = isForward;

     r.profilerInfo = profilerInfo;

     r.overrideConfig = overrideConfig;
     updatePendingConfiguration(curConfig);
     //注意这行代码
     sendMessage(H.LAUNCH_ACTIVITY, r);
 }

ActivityThread.java ::H#handleMessage

public void handleMessage(Message msg) {
    switch (msg.what) {
        case LAUNCH_ACTIVITY: {
            final ActivityClientRecord r = (ActivityClientRecord) msg.obj;
            r.packageInfo = getPackageInfoNoCheck(
                    r.activityInfo.applicationInfo, r.compatInfo);
            //注意这行代码
            handleLaunchActivity(r, null);
        } break;
        ...
    }
}

ActivityThread.java#handleLaunchActivity

private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
    unscheduleGcIdler();
    mSomeActivitiesChanged = true;

    //最终回调目标Activity的onConfigurationChanged()
    handleConfigurationChanged(null, null);
    //初始化wms
    WindowManagerGlobal.initialize();
    //最终回调目标Activity的onCreate  注意这行代码
    Activity a = performLaunchActivity(r, customIntent);
    if (a != null) {
        r.createdConfig = new Configuration(mConfiguration);
        Bundle oldState = r.state;
        //最终回调目标Activity的onStart,onResume.
        handleResumeActivity(r.token, false, r.isForward,
                !r.activity.mFinished && !r.startsNotResumed);

        if (!r.activity.mFinished && r.startsNotResumed) {
            r.activity.mCalled = false;
            mInstrumentation.callActivityOnPause(r.activity);
            r.paused = true;
        }
    } else {
        //存在error则停止该Activity
        ActivityManagerNative.getDefault()
            .finishActivity(r.token, Activity.RESULT_CANCELED, null, false);
    }
}

ActivityThread.java#performLaunchActivity

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {

    ActivityInfo aInfo = r.activityInfo;
    if (r.packageInfo == null) {
        r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
                Context.CONTEXT_INCLUDE_CODE);
    }

    ComponentName component = r.intent.getComponent();
    if (component == null) {
        component = r.intent.resolveActivity(
            mInitialApplication.getPackageManager());
        r.intent.setComponent(component);
    }

    if (r.activityInfo.targetActivity != null) {
        component = new ComponentName(r.activityInfo.packageName,
                r.activityInfo.targetActivity);
    }

    Activity activity = null;
    try {
        java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
        activity = mInstrumentation.newActivity(
                cl, component.getClassName(), r.intent);
        StrictMode.incrementExpectedActivityCount(activity.getClass());
        r.intent.setExtrasClassLoader(cl);
        r.intent.prepareToEnterProcess();
        if (r.state != null) {
            r.state.setClassLoader(cl);
        }
    } catch (Exception e) {
        ...
    }

    try {
        //创建Application对象
        Application app = r.packageInfo.makeApplication(false, mInstrumentation);

        if (activity != null) {
            Context appContext = createBaseContextForActivity(r, activity);
            CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
            Configuration config = new Configuration(mCompatConfiguration);

            activity.attach(appContext, this, getInstrumentation(), r.token,
                    r.ident, app, r.intent, r.activityInfo, title, r.parent,
                    r.embeddedID, r.lastNonConfigurationInstances, config,
                    r.referrer, r.voiceInteractor);

            if (customIntent != null) {
                activity.mIntent = customIntent;
            }
            r.lastNonConfigurationInstances = null;
            activity.mStartedActivity = false;
            int theme = r.activityInfo.getThemeResource();
            if (theme != 0) {
                activity.setTheme(theme);
            }

            activity.mCalled = false;
            if (r.isPersistable()) {
                mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
            } else {
                mInstrumentation.callActivityOnCreate(activity, r.state);
            }
            ...
            r.activity = activity;
            r.stopped = true;
            if (!r.activity.mFinished) {
                activity.performStart();
                r.stopped = false;
            }
            if (!r.activity.mFinished) {
                if (r.isPersistable()) {
                    if (r.state != null || r.persistentState != null) {
                        mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state,
                                r.persistentState);
                    }
                } else if (r.state != null) {
                    mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
                }
            }
            if (!r.activity.mFinished) {
                activity.mCalled = false;
                if (r.isPersistable()) {
                    mInstrumentation.callActivityOnPostCreate(activity, r.state,
                            r.persistentState);
                } else {
                    mInstrumentation.callActivityOnPostCreate(activity, r.state);
                }
                ...
            }
        }
        r.paused = true;

        mActivities.put(r.token, r);

    }  catch (Exception e) {
        ...
    }

    return activity;
}

到此,正式进入了Activity的onCreate, onStart, onResume这些生命周期的过程启动一个Activity的过程到此结束,我实话我已经晕了,大家一定要自己跟一遍代码。

总结

image.png

此图来自gityuan博客

启动流程:

  1. 点击桌面App图标,Launcher进程采用Binder IPC向system_server进程发起startActivity请求;
  2. system_server进程接收到请求后,向zygote进程发送创建进程的请求;
  3. Zygote进程fork出新的子进程,即App进程;
  4. App进程,通过Binder IPC向sytem_server进程发起attachApplication请求;
  5. system_server进程在收到请求后,进行一系列准备工作后,再通过binder IPC向App进程发送scheduleLaunchActivity请求;
  6. App进程的binder线程(ApplicationThread)在收到请求后,通过handler向主线程发送LAUNCH_ACTIVITY消息;
  7. 主线程在收到Message后,通过发射机制创建目标Activity,并回调Activity.onCreate()等方法。
    到此,App便正式启动,开始进入Activity生命周期,执行完onCreate/onStart/onResume方法,UI渲染结束后便可以看到App的主界面

相关文章

网友评论

      本文标题:从startActivity一步步到穿越进程壁垒

      本文链接:https://www.haomeiwen.com/subject/zujuextx.html