Android 源码分析之——Activity启动流程

来源:互联网 发布:计算量子电路矩阵 编辑:程序博客网 时间:2024/05/21 10:18

好久没有记录自己最近所学了。一个月前说要了解Activity的启动流程,但是由于偷懒,迟迟没有下手了解。后来,看了一些文字以及书籍,发现Activity的启动流程十分之复杂。而以我的实力,只能做一些简单的分析了。

我们平时,在启动Activity的时候,通过调用Activity.startActivity(intent),去启动的。我们就从这里追踪进去。

@Overridepublic void startActivity(Intent intent) {    this.startActivity(intent, null);}
@Overridepublic 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);    }}

最后,都会调用startActivityForResult(Intent,int,options)这个方法。看看这个方法。

public void startActivityForResult(Intent intent, int requestCode, @Nullable Bundle options) {   if (mParent == null) {       //关键代码       Instrumentation.ActivityResult ar =           mInstrumentation.execStartActivity(this, mMainThread.getApplicationThread(), mToken, this,intent, requestCode, options);       //省略代码       ......   }}

一般而言,启动Activty都会经过上面标注的关键代码那一块,跟进去看看。
找到Instrumentation类,然后再找到execStartActivity方法。

public ActivityResult execStartActivity(        Context who, IBinder contextThread, IBinder token, Activity target,        Intent intent, int requestCode, Bundle options) {    IApplicationThread whoThread = (IApplicationThread) contextThread;    Uri referrer = target != null ? target.onProvideReferrer() : null;    if (referrer != null) {        intent.putExtra(Intent.EXTRA_REFERRER, referrer);    }    //检查是否存在这个Activity    if (mActivityMonitors != null) {        synchronized (mSync) {            final int N = mActivityMonitors.size();            for (int i=0; i<N; i++) {                final ActivityMonitor am = mActivityMonitors.get(i);                if (am.match(who, null, intent)) {                    am.mHits++;                    if (am.isBlocking()) {                        return requestCode >= 0 ? am.getResult() : null;                    }                    break;                }            }        }    }    try {        intent.migrateExtraStreamToClipData();        intent.prepareToLeaveProcess();        //打开Acitivti的地方        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;}

我作为一个Android新手,跟踪源码到这里,就已经被卡住了。
上面备注的真正启动Activity的哪几行代码里,ActivityManagerNative.getDefault()放回的是一个binder对象,而binder机制,我还没有做过一些相应的研究,导致我研究到这个部分的时候,很吃力。

在网上查阅资料,后来才知道,ActivityManagerNative.getDefault()返回的对象,是ActivityManagerServer对象。至于,如何为啥返回的就是ActivityManagerServer对象,以后我做相应的研究之后,再做记录。

打开ActivityManagerServer,发现它是击沉ActivityManagerNative的,所以,网上的资料是对的,ActivityManagerNative.getDefault()确实是ActivityManagerServer的实例。

在Instrumentation的execStartActivity里,调用了ActivityManagerServer的startActivity方法,现在,看到这个方法。这里要提醒一下,ActivityManagerServer里有一个内部类,叫做AppTaskImpl,里面也有startActivity方法。千万不要看错了

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

这个方法最终会调用到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, int userId,IActivityContainer iContainer, TaskRecord inTask) {         .....        //关键代码        int res = startActivityLocked(caller, intent, resolvedType, aInfo,voiceSession, voiceInteractor, resultTo, resultWho,requestCode, callingPid, callingUid, callingPackage,realCallingPid, realCallingUid, startFlags, options,componentSpecified, null, container, inTask);       .....        return res;    }}

这个函数做一些信息保存,然后调用了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 componentSpecified, ActivityRecord[] outActivity, ActivityContainer container,TaskRecord inTask) {        ....        err = startActivityUncheckedLocked(r, sourceRecord, voiceSession, voiceInteractor,                startFlags, true, options, inTask);       ...        return err;    }

这个函数的功能是做一些错误检测,然后记录启动的进程。最后调用 了startActivityUncheckedLocked()方法。
startActivityUncheckedLocaked()方法特别的长,里面猜测做一些判断启动模式得判断。

最后,会调用ActivityStack.resumeTopActivityLocked()方法。
之后,会不断在ActivityStack与ActivityStackSupervisor这两个类来回调用,做一些处理。例如:判断要启动的Activity是否在栈顶,如果在栈顶,就不做任何事情了等等。

经过多次“纠缠”与binder通信,最后,会调用ActivityStackSupervisor.realStartActivityLocked()方法。

final boolean realStartActivityLocked(ActivityRecord r,        ProcessRecord app, boolean andResume, boolean checkConfig)        throws RemoteException {    .....        //关键代码        app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration),r.compat, r.launchedFromPackage, r.task.voiceInteractor, app.repProcState,r.icicle, r.persistentState, results, newIntents, !andResume,mService.isNextTransitionForward(), profilerInfo);    ....    return true;}

这里通过binder机制,调用了ActivityThread.scheduleLaunchActivity()方法。

public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,ActivityInfo info, Configuration curConfig, 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;            updatePendingConfiguration(curConfig);            sendMessage(H.LAUNCH_ACTIVITY, r);        }

到这里就很明朗了。准备一些信息,然后调用sendMessage发送LAUNCH_ACTIVITY消息。

    private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {        if (DEBUG_MESSAGES) Slog.v(            TAG, "SCHEDULE " + what + " " + mH.codeToString(what)            + ": " + arg1 + " / " + obj);        Message msg = Message.obtain();        msg.what = what;        msg.obj = obj;        msg.arg1 = arg1;        msg.arg2 = arg2;        if (async) {            msg.setAsynchronous(true);        }        mH.sendMessage(msg);    }

这里可以看到,是mH这个handle在发送消息,直接看mH对于LAUNCH_ACTIVITY的处理。

case LAUNCH_ACTIVITY: {   .....   handleLaunchActivity(r, null);   .....} break;

在mH中,对于LAUNCH_ACTIVITY这个消息的处理就是调用了handleLaunchActivity();
handleLaunchActivity里主要做了两件事,第一件事调用了performLaunchActivity()方法,第二件事调用了handleResumeActivity()方法。

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {    ......    Activity activity = null;    try {        java.lang.ClassLoader cl = r.packageInfo.getClassLoader();        //创造Activity实例,终于到这里了        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);        }    }       try{       //调用了onCreate方法            if (r.isPersistable()) {mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);            } else {mInstrumentation.callActivityOnCreate(activity, r.state);            }            if (!activity.mCalled) {                throw new SuperNotCalledException(                    "Activity " + r.intent.getComponent().toShortString() +                    " did not call through to super.onCreate()");            }            r.activity = activity;            r.stopped = true;            //调用start方法            if (!r.activity.mFinished) {                activity.performStart();                r.stopped = false;            }           .....    return activity;}

performLaunchActivity()中,调用了onCreate()与onStart()方法。
handleResumeActivity()中,调用了onResume()方法。

 final void handleResumeActivity(IBinder token,            boolean clearHide, boolean isForward, boolean reallyResume) {        .....       //调用了onResume()            performResumeActivity(token, clearHide);       ....}

Activity的启动超级复杂,毕竟是最常用的四大组件之一。作为一位开发者,偶尔研究一下源码是好事,但是切记不要沉迷于细节,特别是在功力还不够的时候,沉迷于细节会很浪费时间。

我这个学习记录,只是很简单的分析了Activity的启动的源码流程框架而已。
总后总结一下:
Actiivty.startActivityForResult()
–> mInstrumentation.execStartActivity()
–> int result = ActivityManagerNative.getDefault().startActivity();
–> startActivityAsUser();
–> startActivityMayWait()
–> startActivityUncheckedLocked()
–> 开始多次在ActivityStack与ActivityStackSupervisor来回调用
–>ActivityStackSupervisor.realStartActivityLocked()
–>ActivityThread.scheduleLaunchActivity()
–>sendMessage(H.LAUNCH_ACTIVITY, r);
–> handleLaunchActivity(r, null);
–>performLaunchActivity()与handleResumeActivity()
–>onCreare()与onStart()与onResume()

原创粉丝点击