从Android源码分析Activity加载流程

概述:startActivity->startActivityForResult->Instrumentation::execStartActivity->scheduleLaunchActivity->performLaunchActivity->handleLaunchActivity->handleResumeActivity

本文通过Android源码介绍Activity的加载过程。首先从Activity.java中的startActivity开始:

@Override
public void startActivity(Intent intent, @Nullable Bundle options) {    
    if (options != null) {        
        startActivityForResult(intent, -1, options);    
    } else {                   
        startActivityForResult(intent, -1);    
    }
}

可以看出startActivity也是通过调用startActivityForResult实现的,接下来就研究startActivityForResult的实现。

Activity.java

@Override
public void startActivityForResult(String who, Intent intent, int requestCode, @Nullable Bundle options) {    
    Uri referrer = onProvideReferrer();    
    if (referrer != null) {        
        intent.putExtra(Intent.EXTRA_REFERRER, referrer);    
    }    

    Instrumentation.ActivityResult ar = mInstrumentation.execStartActivity( 
        this, 
        mMainThread.getApplicationThread(), 
        mToken, 
        who,            
        intent, 
        requestCode, 
        options);    
    if (ar != null) {        
        mMainThread.sendActivityResult(mToken, who, requestCode, ar.getResultCode(), ar.getResultData());
    }    

    cancelInputsAndStartExitTransition(options);
}

这里通过Instrumentation类的execStartActivity方法来启动Activity。

Instrumentation.java

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

    if (mActivityMonitors != null) {        
        synchronized (mSync) {            
            final int N = mActivityMonitors.size();            
            for (int i=0; i= 0 ? am.getResult() : null;                                      
                    }                    
                    break;                
                }            
            }        
        }    
    }    

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

whoThread是一个实现了IApplicationThread接口的类的实例,IApplicationThread接口提供了系统跟应用(application)交互的API,当应用启动的时候,application将实现了IApplicationThread接口的实例传入Activity Manager,Activity Manager通过该实例指导应用进行诸如启动、暂停、停止Activity等一系列操作。

public interface IApplicationThread extends IInterface {    
    void schedulePauseActivity(IBinder token, boolean finished, boolean userLeaving,  
        int configChanges, boolean dontReport) throws RemoteException;        
    void scheduleStopActivity(IBinder token, boolean showWindow,  int configChanges) throws RemoteException;    
    void scheduleWindowVisibility(IBinder token, boolean showWindow) throws RemoteException;    
    void scheduleSleeping(IBinder token, boolean sleeping) throws RemoteException;    
    void scheduleResumeActivity(IBinder token, int procState, boolean isForward, Bundle resumeArgs) throws RemoteException;    
    void scheduleSendResult(IBinder token, List results) throws RemoteException;
    void scheduleLaunchActivity(.....);
    void scheduleRelaunchActivity(......);
    void scheduleDestroyActivity(......);
    ...
}

其中启动Activity的函数是scheduleLaunchActivity,该函数的实现在ActivityThread类的一个私有类ApplicationThread里:
ActivityThread.java

public final class ActivityThread {
    ...
    private class ApplicationThread extends ApplicationThreadNative {
        @Override
        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 pendingResults, List 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);
    }
    ...
}

其中ApplicationThreadNative实现了IApplicationThread接口:

public abstract class ApplicationThreadNative extends Binder  
implements IApplicationThread {
    ...  
}

在ApplicationThread中我们看到scheduleLaunchActivity的实现,该函数参数众多,包括传入Activity的intent,标识该Activity的token,存储AndroidManifest.xml中标记段信息的activityInfo,存储系统级别和用户级别的配置curConfig(如屏幕方向,当前国家和字体缩放设置等,通过getResources().getConfiguration()获得)等。
将这些参数赋值给ActivityClientRecord,然后通过sendMessage发送一个类型为LAUNCH_ACTIVITY的message。
我们看看sendMessage的实现:

ActivityThread.java

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

sendMessage就是构造了一个Message并通过H类型的Handler发送出去。看看H的定义:

ActivityThread.java

private class H extends Handler {    
    public static final int LAUNCH_ACTIVITY         = 100;    
    public static final int PAUSE_ACTIVITY          = 101;    
    public static final int PAUSE_ACTIVITY_FINISHING= 102;    
    public static final int STOP_ACTIVITY_SHOW      = 103;    
    public static final int STOP_ACTIVITY_HIDE      = 104;    
    public static final int SHOW_WINDOW             = 105;    
    public static final int HIDE_WINDOW             = 106;    
    public static final int RESUME_ACTIVITY         = 107;
    ...
    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;        
        case RELAUNCH_ACTIVITY: {            
            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityRestart");            
            ActivityClientRecord r = (ActivityClientRecord)msg.obj;            
            handleRelaunchActivity(r);            
            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);        
            }
            break;
            ...
        }
    }
    ...
}

在H类型的Handler里处理了各种类型的消息,通过函数handleLaunchActivity处理LAUNCH_ACTIVITY消息:

ActivityThread.java

private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
    ...
    WindowManagerGlobal.initialize();
    Activity a = performLaunchActivity(r, customIntent);
    if (a != null) {    
        r.createdConfig = new Configuration(mConfiguration);    
        Bundle oldState = r.state;    
        handleResumeActivity(r.token, false, r.isForward, !r.activity.mFinished && !r.startsNotResumed);    
        if (!r.activity.mFinished && r.startsNotResumed) {
            try {    
                r.activity.mCalled = false;    
                mInstrumentation.callActivityOnPause(r.activity);
                ...
            }
          ...
        }
    } else {
        ...
    }
}

这里面主要包括三个操作,performLaunchActivity启动Activity,handleResumeActivity来Resume Activity,最后通过Instrumentation的callActivityOnPause函数来OnPause Activity。
来看看performLaunchActivity的实现:

ActivityThread.java

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) {    
        if (!mInstrumentation.onException(activity, e)) {        
            throw new RuntimeException("Unable to instantiate activity " + component + ": " + e.toString(), e);    
        }
    }
    try {    
        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);            
            }            
            if (!activity.mCalled) {                
                throw new SuperNotCalledException( "Activity " + r.intent.getComponent().toShortString() + " did not call through to super.onCreate()");            
            }            
            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);                
            }                
            if (!activity.mCalled) {                    
                throw new SuperNotCalledException("Activity " + r.intent.getComponent().toShortString() + " did not call through to super.onPostCreate()");                
            }            
        }        
    }        
    r.paused = true;        
    mActivities.put(r.token, r);    
    } catch (SuperNotCalledException e) {        
        throw e;    
    } catch (Exception e) {        
        if (!mInstrumentation.onException(activity, e)) {            
            throw new RuntimeException("Unable to start activity " + component + ": " + e.toString(), e);        
        }    
    }    
    return activity;
}

首先通过java.lang.ClassLoader,调用Instrumentation的newActivity方法,根据Activity的名称加载Activity类:

Instrumentation.java

public Activity newActivity(ClassLoader cl, String className, Intent intent)        
    throws InstantiationException, IllegalAccessException, ClassNotFoundException {    
        return (Activity)cl.loadClass(className).newInstance();
}

然后通过createBaseContextForActivity生成Activity的context,并通过activity.attach方法将Activity的context和其他属性赋给Activity。接着调用Instrumentation的 callActivityOnCreate方法, callActivityOnRestoreInstanceState 方法和callActivityOnPostCreate 方法, 分别对应Activity的onCreate,onRestoreInstanceState和onPostCreate方法。这样就在performLaunchActivity函数中完成了Activity的加载和初始化过程。

回到handleLaunchActivity函数,在performLaunchActivity完成后,通过handleResumeActivity方法使得Activity完成onResume的准备工作,进入onResume状态。最后,调用Instrumentation的callActivityOnPause方法,使得Activity进入onPause的状态,这样,当Activity最终展示出来的时候,就会从onResume作为开始。至此,Activity加载完毕。

你可能感兴趣的:(从Android源码分析Activity加载流程)