Activity 启动过程源码解析

总流程图

Activity启动流程.jpg

启动

我们在代码中启动Activity都使用 Context.startActivity()的方式;来启动Activity。那么在这个过程中到底发生了什么?跟着源码来看一下。

首先Context.startActivity()之后会调用Conetxt的子类ContextWrapper,这是一个Context的包装类。Context还有一个子类是ContextImpl,这是Context的实现子类。

在ContextWrapper中的代码是这样的:

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

其中mBase就是Attach进来的Context,他的实现就是在ContextImpl里面。

@Override
public void startActivity(Intent intent, Bundle options) {
    warnIfCallingFromSystemProcess();
    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
        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);
}

在这个方法内部会调用Instrumentation。这个类封装着Activity的各种操作。所以在这边跳转到Instrumentation.execStartActivity()的执行方法。

public ActivityResult execStartActivity(
        Context who, IBinder contextThread, IBinder token, Activity target,
        Intent intent, int requestCode, Bundle options) {
   
    ...
    ...
    
    try {
        intent.migrateExtraStreamToClipData();
        intent.prepareToLeaveProcess();
        int result = ActivityManagerNative.getDefault()
            .startActivity(whoThread, who.getBasePackageName(), intent,
                    intent.resolveTypeIfNeeded(who.getContentResolver()),
                    token, target != null ? target.mEmbeddedID : null,
                    requestCode, 0, null, options);
        checkStartActivityResult(result, intent);
    } catch (RemoteException e) {
        throw new RuntimeException("Failure from system", e);
    }
    return null;
        
}

在这个方法里面有这么一绝ActivityManagerNative.getDefault().startActivity() 我们看一下ActivityManagerNative 是什么东西.

ActivityManagerNative类的定义是这样的:

public abstract class ActivityManagerNative extends Binder implements IActivityManager{}

这边ActivityManagerNative是一个典型的Binder对象,继承Binder并实现一个接口。这边如果不理解Binder,建议先去学习了解Binder,了解Android的IPC机制。4大组件底层的启动大部分都是通过Binder进行关联启动。

如果了解Binder,那我们继续下去,我们在写AIDL的时候,IDE自动帮我们生成Binder代码,我们知道Binder有两个内容,一个是Stub,用来服务端通信的,还有一个Proxy代理用来客户端信息。而ActivityManagerNative本身就是一个Stub,它是由Google自己写的一个Binder。ActivityManagerNative 里面也有一个Proxy。就是ActivityManagerProxy。

class ActivityManagerProxy implements IActivityManager{
    private IBinder mRemote;

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

    public IBinder asBinder()
    {
        return mRemote;
    }
    
    .....
    
}

看这个跟IDE自动生成的代码是一样的。
我们接着上面的分析,在ContextImpl中ActivityManagerNative.getDefault(),实际上是一由一个自己封装Singleton单例对象。在get()的时候如果是第一次则会调用create().

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;
        }
    };

Singleton.java

public abstract class Singleton<T> {
    private T mInstance;

    protected abstract T create();

    public final T get() {
        synchronized (this) {
            if (mInstance == null) {
                mInstance = create();
            }
            return mInstance;
        }
    }
}

在这里将获取的IBinder转成IActivityManager 对象。ActivityManagerNative.getDefault().startActivity()实际上是调用IActivityManager.startActivity(). 由上面分析的Binder,我们可以知道IActivityManager.startActivity()就是从客户端调用startActivity,也就是在Proxy里面调用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 {
    
    ...
    
    mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0);
    reply.readException();
    int result = reply.readInt();
    reply.recycle();
    data.recycle();
    return result;
}

参数一大堆,看我们关心的mRemote.transact()方法,回调到AMN的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;
        int result = startActivity(app, callingPackage, intent, resolvedType,
                resultTo, resultWho, requestCode, startFlags, profilerInfo, options);
        reply.writeNoException();
        reply.writeInt(result);
        return true;
    }
    }
}

这里调的startActivity实际上是调用ActivityManagerService中的startActivity,AMS是ActivityManagerNative的具体实现类。

@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());
}

内部接着调用startActivityAsUser()。

@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.startActivityMayWait()这个方法。ActivityStackSupervisor 这个类有点像工具类,封装Activity的各种操作。看一下startActivityMayWait这个方法做了什么。

 final int startActivityMayWait(...){
    ...
     // Collect information about the target of the Intent.
    //收集目标Activity的信息.
    ActivityInfo aInfo =
            resolveActivity(intent, resolvedType, startFlags, profilerInfo, userId);
    ...
    synchronized (mService) {
        ...
        //启动Activity
        int res = startActivityLocked(caller, intent, resolvedType, aInfo,
                voiceSession, voiceInteractor, resultTo, resultWho,
                requestCode, callingPid, callingUid, callingPackage,
                realCallingPid, realCallingUid, startFlags, options, ignoreTargetSecurity,
                componentSpecified, null, container, inTask);

        Binder.restoreCallingIdentity(origId);
        ...
    }
    ...
    
 }

这个方法也是一大堆参数。先不去管他,看具体的实现,首先是收集目标Activity的信息,然后接着调用startActivityLocked。

final int startActivityLocked(...){
    ...
    if (err != ActivityManager.START_SUCCESS) {
        if (resultRecord != null) {
            //这个干吗?最后回调onActivityResult,就是说startActivity最后还是会调用startActivityForResult
            resultStack.sendActivityResultLocked(-1,
                resultRecord, resultWho, requestCode,
                Activity.RESULT_CANCELED, null);
        }
        ActivityOptions.abort(options);
        return err;
    }
    ...
    //也是调用startActivityUncheckedLocked方法.
    doPendingActivityLaunchesLocked(false);

    // 从这进去
    err = startActivityUncheckedLocked(r, sourceRecord, voiceSession, voiceInteractor,
            startFlags, true, options, inTask);
    ...
}

startActivityLocked这个方法很长,重点看着几个,这里面有好几次调用到resultStack.sendActivityResultLocked,而这个方法最终回调onActivityResult。
往下看这里最后调startActivityUncheckedLocked方法。

startActivityUncheckedLocked 也是一个大方法,最后是调用resumeTopActivitiesLocked(targetStack, null, options);过程就不看,代码太多太复杂。

 boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target,
        Bundle targetOptions) {
    ...
    boolean result = false;
    if (isFrontStack(targetStack)) {
        result = targetStack.resumeTopActivityLocked(target, targetOptions);
    }
    ...
}

回调到ActivityStack的resumeTopActivityLocked。

final boolean resumeTopActivityLocked(ActivityRecord prev, Bundle options) {
    ...
    try{
        ...
        result = resumeTopActivityInnerLocked(prev, options);
    }
    ...
}

回调resumeTopActivityInnerLocked,这个方法也是一个大方法,代码很多,在这里面进行一系列判断操作后调用mStackSupervisor.startSpecificActivityLocked又回到ActivityStackSupervisor中去了。

而在startSpecificActivityLocked方法中调用realStartActivityLocked这个方法

final boolean realStartActivityLocked(ActivityRecord r,
    ProcessRecord app, boolean andResume, boolean checkConfig)
    throws RemoteException {
    ...
    //启动Activity
    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);
    ...
}

这边开始调用app.thread.scheduleLaunchActivity,这个是回到应用进程中去。这里的app.thread是IApplicationThread。而在ActivityManagerNative里的START_SERVICE_TRANSACTION有这句: IApplicationThread app = ApplicationThreadNative.asInterface(b); 我们的这个app.thread也是ApplicationThreadNative里的Binder。这边又是一个Binder对象。

同样ApplicationThreadNative也是一个Stub,里面的ApplicationThreadProxy是一个Proxy。所以这里app.thread.scheduleLaunchActivity()实际是ApplicationThreadNative.scheduleLaunchActivity().

public final void scheduleLaunchActivity(...){
    ...
    mRemote.transact(SCHEDULE_LAUNCH_ACTIVITY_TRANSACTION, data, null,
                IBinder.FLAG_ONEWAY);
    data.recycle();
}

回调到ApplicationThreadNative 的onTransact中:

case SCHEDULE_LAUNCH_ACTIVITY_TRANSACTION:
 {
    ...
    scheduleLaunchActivity(intent, b, ident, info, curConfig, overrideConfig, compatInfo,
                    referrer, voiceInteractor, procState, state, persistentState, ri, pi,
                    notResumed, isForward, profilerInfo);
    return true;
 }

scheduleLaunchActivity的具体实现是在applicationThread中:

@Override
public final void scheduleLaunchActivity(...){
    ...
    sendMessage(H.LAUNCH_ACTIVITY, r);
}

这边通过sendMessage()发送消息,由H来处理,H是系统的Handler。

public void handleMessage(Message msg) {
     switch (msg.what) {
        case LAUNCH_ACTIVITY: {
            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
            final ActivityClientRecord r = (ActivityClientRecord) msg.obj;

            r.packageInfo = getPackageInfoNoCheck(
                    r.activityInfo.applicationInfo, r.compatInfo);
            handleLaunchActivity(r, null);
            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
        } break;
     }
}

调用handleLaunchActivity,在handleLaunchActivity里面是:

private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
    ...
    //准备启动Activity
    Activity a = performLaunchActivity(r, customIntent);
    
    if (a != null) {
        ...
        //处理onResume方法
        handleResumeActivity(r.token, false, r.isForward,
                !r.activity.mFinished && !r.startsNotResumed);
    }
}

performLaunchActivity 准备启动。

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
    //获取待启动的Activity的信息.
    ActivityInfo aInfo = r.activityInfo;
    ...
    //通过newActivity方式使用类加载器创建Activity对象.
    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) {
        if (!mInstrumentation.onException(activity, e)) {
            throw new RuntimeException(
                "Unable to instantiate activity " + component
                + ": " + e.toString(), e);
        }
    }
    
    //通过makeApplication方法创建Application.
    try {
        Application app = r.packageInfo.makeApplication(false, mInstrumentation);
        ...
        if (r.isPersistable()) {
       //回调onCreate()
            mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
        } else {
            mInstrumentation.callActivityOnCreate(activity, r.state);
        }
        
        ...
        if (!r.activity.mFinished) {
        //回调onStart。
            activity.performStart();
            r.stopped = false;
        }
        ...
    }
    ...
}

又回到 Instrumentation 中调用callActivityOnCreate;

public void callActivityOnCreate(Activity activity, Bundle icicle,
        PersistableBundle persistentState) {
    prePerformCreate(activity);
    activity.performCreate(icicle, persistentState);
    postPerformCreate(activity);
}

activity.performCreate 调用Activity的performCreate。

final void performCreate(Bundle icicle, PersistableBundle persistentState) {
    restoreHasCurrentPermissionRequest(icicle);
    onCreate(icicle, persistentState);
    mActivityTransitionState.readState(icicle);
    performCreateCommon();
}

至此Activity启动成功并调用onCreate().

那Activity生命周期里接下去调用onStart()方法。我们看performLaunchActivity在callActivityOnCreate后面还调用了performStart(),就是回调onStart()方法。

onResume()方法在哪里回调,我们看handleLaunchActivity方法里面在调用performLaunchActivity之后还调用了handleResumeActivity(),这个就是回调onResume()的方法。其他的生命周期方法也是一样的模式。至此Activity启动源码阅读结束

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 195,898评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,401评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 143,058评论 0 325
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,539评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,382评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,319评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,706评论 3 386
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,370评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,664评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,715评论 2 312
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,476评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,326评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,730评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,003评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,275评论 1 251
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,683评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,877评论 2 335

推荐阅读更多精彩内容