Activity的启动过程详解

Activity的作用

Activity是用于展示界面给用户看的。并能接收用户输入的信息来进行交互。

Activity的使用

Activity是一个很重要的一个组件,系统对Activity的内部细节做了很多封装,从而使activity的使用起来特别的简单:。

startActivity(new Intent(this,LocationManagerActivity.class));

非常的简单。系统到底是如何启动的?我们去看看源码到底是怎么启动的?由于系统启动Activity的源码内部细节过于复杂,我们只注重启动Activity的整体过程,还有思想。代码的编写每个人都有自己的风格,思想是最重要的。

启动Activity的源码分析

先看看start Activity方法

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

可以看到startActivity有不同的重载方法,但是最终都是调用了startActivityForResult方法,去看看:

    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);
            if (ar != null) {
                mMainThread.sendActivityResult(
                    mToken, mEmbeddedID, requestCode, ar.getResultCode(),
                    ar.getResultData());
            }
            if (requestCode >= 0) {
                // If this start is requesting a result, we can avoid making
                // the activity visible until the result is received.  Setting
                // this code during onCreate(Bundle savedInstanceState) or onResume() will keep the
                // activity hidden during this time, to avoid flickering.
                // This can only be done when a result is requested because
                // that guarantees we will get information back when the
                // activity is finished, no matter what happens to it.
                mStartedActivity = true;
            }

            cancelInputsAndStartExitTransition(options);
            // TODO Consider clearing/flushing other event sources and events for child windows.
        } else {
            if (options != null) {
                mParent.startActivityFromChild(this, intent, requestCode, options);
            } else {
                // Note we want to go through this method for compatibility with
                // existing applications that may have overridden it.
                mParent.startActivityFromChild(this, intent, requestCode);
            }
        }
    }

在代码的内部调用了 mInstrumentation.execStartActivity( this,mMainThread.getApplicationThread(), mToken, this,
intent, requestCode, options);这里有个参数需要说明一些,mMainThread.getApplicationThread()的值其实就是Activity Thread类中内部类ApplicationThread,这是一个Binder对象。用于IPC通信用的。

进入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);
        }
        if (mActivityMonitors != null) {
            synchronized (mSync) {
                final int N = mActivityMonitors.size();
                for (int i=0; ifinal 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();
            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()方法来启动Activity。ActivityManagerNative.getDefault()是什么?去看看代码:

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


    private static final Singleton gDefault = new Singleton(){

        protected IActivityManager create(){
            IBinder b = ServiceManager.getService("activity");
            ...
            IActivityManager am = asInterface(b);
            ...

        }
    };

从代码中看到返回的是IActivityManager类型。而ActivityManagerNative是继承于Binder并实现了IActivityManager接口,ActivityManagerService继承与ActivityManagerNative,它是IActivityManager具体的实现类。因此ActivityManagerNative.getDefault()返回的值就是ActivityManagerService。所以启动Activity的任务交到了AmS,

而在AmS服务端还会调用了一系列的方法。如图是在服务端的调用顺序,我们不深究代码的细节,反正就经过了这样的调用顺序。

Activity的启动过程详解_第1张图片

我们看到最后一个方法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);

    ...

在代码中调用了app.thread.scheduLaunchActivity()的方法。app.thread的类型是IApplicationThread。

IApplicationThread是一个接口。
ApplicationThreadNative类继承了Binder和实现了该接口,该类是一个抽象类ApplicationThread继承了ApplicationThreadNative。

    public interface IApplicationThread extends IInterface{...}

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

    private class ApplicationThread extends ApplicationThreadNative {...}

因此app.thread的真正的类型是Application Thread。

经过这样的调用,Activity的启动过程就回到了Application Thread的scheduleLaunchActivity方法中,ApplicationThread类是ActivityThread的内部类。进入看看该方法的代码:


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

            updatePendingConfiguration(curConfig);

            sendMessage(H.LAUNCH_ACTIVITY, r);
        }

在上面的代码中,调用了 一个很重要的方法 sendMessage(H.LAUNCH_ACTIVITY, r);去看看这是什么:


    private void sendMessage(int what, Object obj) {
        sendMessage(what, obj, 0, 0, false);
    }

    private void sendMessage(int what, Object obj, int arg1) {
        sendMessage(what, obj, arg1, 0, false);
    }

    private void sendMessage(int what, Object obj, int arg1, int arg2) {
        sendMessage(what, obj, arg1, arg2, false);
    }

    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(int what, Object obj, int arg1, int arg2, boolean async)方法。

在这个方法 的内部调用了 mH.sendMessage(msg);mH是一个H的对象,而H继承与Handler

    final H mH = new H();
   private class H extends Handler  {...}  

因此sendMessage的作用其实就是发送了一条H.LAUNCH_ACTIVITY消息给H类处理。从Handler的运行机制知道,发送异步消息,最终会回调到Handler的handleMessage()的方法中,我们去看看H类中的handler Message()方法处理LAUNCH_ACTIVITY的代码:

  public void handleMessage(Message msg) {
            if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
            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;

        ...
        ...
        ...

从上面的代码可以看到,Activity的启动就交给了 handleLaunchActivity(r, null);我们去看看该方法:

      private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {

        Activity a = performLaunchActivity(r, customIntent);
        ......
        if (a != null) {
            ......
            handleResumeActivity(r.token, false, r.isForward,
                    !r.activity.mFinished && !r.startsNotResumed);
            ......
        }
         .......
    }
}

然后又交给了performLaunchActivity()方法,返回了Activity,想必在这个方法里完成了Activity对像的创建和启动。进去看看

 private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
        ......

        Activity activity = null;
       ......
            java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
            activity = mInstrumentation.newActivity(
                    cl, component.getClassName(), r.intent);

.....

            Application app = r.packageInfo.makeApplication(false, mInstrumentation);

......

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

......

  if (r.isPersistable()) {
                    mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
                } else {
                    mInstrumentation.callActivityOnCreate(activity, r.state);
                }

       ......

        return activity;
    }

在这个方法里,做了几个重要的操作:

通过Instrumentation的newActvity的方法创建通过类加载器创建出了Activity对象。

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

创建Application对象

  public Application makeApplication(boolean forceDefaultAppClass,
                                       Instrumentation instrumentation) {
        if (mApplication != null) {
            return mApplication;
        }

        Application app = null;

        String appClass = mApplicationInfo.className;
        if (forceDefaultAppClass || (appClass == null)) {
            appClass = "android.app.Application";
        }

        try {
            java.lang.ClassLoader cl = getClassLoader();
            if (!mPackageName.equals("android")) {
                initializeJavaContextClassLoader();
            }
            ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
            app = mActivityThread.mInstrumentation.newApplication(
                    cl, appClass, appContext);
            appContext.setOuterContext(app);
        } catch (Exception e) {...}

    ...
    ...



        return app;
    }

在LoadedApk类中的makeApplication方法,通过Instrumentation的newApplication方法,在方法的内部也是类加载器来创建出一个Application对象。

public Application newApplication(ClassLoader cl, String className, Context context)
            throws InstantiationException, IllegalAccessException, 
            ClassNotFoundException {
        return newApplication(cl.loadClass(className), context);
    }
 static public Application newApplication(Class clazz, Context context)
            throws InstantiationException, IllegalAccessException, 
            ClassNotFoundException {
        Application app = (Application)clazz.newInstance();
        app.attach(context);
        return app;
    }

创建ContextImpl和通过Activity的attach方法初始化一些重要的数据。

如果Application对象是第一次创建通过mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState)方法回调到Application的onCreate的方法。

通过 mInstrumentation.callActivityOnCreate(activity, r.state);方法回调到Activity的onCreate方法。

当回调到Activity的onCreate方法时,其实Activity的启动就已经完成了。

END

你可能感兴趣的:(Android,源码分析系列)