Activity的启动过程(Android开发艺术探索学习笔记)

来源:互联网 发布:写作软件app 编辑:程序博客网 时间:2024/05/21 19:40

在Android系统中,应用程序是由Launcher启动起来的。其实,Launcher本身也是一个应用程序,其它的应用程序安装后,就会在Launcher界面上出现一个相应的图标,点击这个图标时,Launcher就会把对应的应用程序启动起来。Launcher部分源码如下(Launcher源码地址):

public final class Launcher extends Activity implements View.OnClickListener, OnLongClickListener {    ……    /**     * Launches the intent referred by the clicked shortcut.     *     * @param v The view representing the clicked shortcut.     */    public void onClick(View v) {        Object tag = v.getTag();        if (tag instanceof ApplicationInfo) {            // Open shortcut            final Intent intent = ((ApplicationInfo) tag).intent;            startActivitySafely(intent);        } else if (tag instanceof FolderInfo) {            handleFolderClick((FolderInfo) tag);        }    }    void startActivitySafely(Intent intent) {        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);        try {            startActivity(intent);        } catch (ActivityNotFoundException e) {            Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();        } catch (SecurityException e) {            Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();            e(LOG_TAG, "Launcher does not have the permission to launch " + intent +                    ". Make sure to create a MAIN intent-filter for the corresponding activity " +                    "or use the exported attribute for this activity.", e);        }    }    ……}

从上面的代码可以知道,在Launcher的onClick()中调用了startActivitySafely(),在startActivitySafely()中又调用了startActivity()。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(),mInstrumentation是一个Instrumentation类型的成员变量。看一下Instrumentation类的定义:

/** * Base class for implementing application instrumentation code.  When running * with instrumentation turned on, this class will be instantiated for you * before any of the application code, allowing you to monitor all of the * interaction the system has with the application.  An Instrumentation * implementation is described to the system through an AndroidManifest.xml's * <instrumentation> tag. */

从定义可知Instrumentation用来监控应用程序和系统的交互。
我们还看到execStartActivity()传进去的一个变量是mMainThread.getApplicationThread(),这里的mMainThread也是Activity类的成员变量,它的类型是ActivityThread,它代表的是应用程序的主线程。这里通过mMainThread.getApplicationThread获得它里面的ApplicationThread成员变量,它是一个Binder对象,后面我们会看到,ActivityManagerService会使用它来和ActivityThread来进行进程间通信。从源码中可以看到ApplicationThread是ActivityThread的一个内部类。
接着继续看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);        }        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();            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()。ActivityManagerService(简称AMS)继承自ActivityManagerNative,而ActivityManagerNative继承自Binder并且实现了IActivityManager,因此AMS也是一个Binder,它是IActivityManager的具体实现。
在ActivityManagerNative中AMS这个Binder以单例模式对外提供,getDefault()返回的是一个Singleton的泛型类。

public abstract class ActivityManagerNative extends Binder implements IActivityManager{    ……    /**     * Retrieve the system's default/global activity manager.     */    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;        }    };    ……}

Instrumentation的execStartActivity()调用ActivityManagerService的startActivity()后又调用了checkStartActivityResult():

    public static void checkStartActivityResult(int res, Object intent) {        if (res >= ActivityManager.START_SUCCESS) {            return;        }        switch (res) {            case ActivityManager.START_INTENT_NOT_RESOLVED:            case ActivityManager.START_CLASS_NOT_FOUND:                if (intent instanceof Intent && ((Intent)intent).getComponent() != null)                    throw new ActivityNotFoundException(                            "Unable to find explicit activity class "                            + ((Intent)intent).getComponent().toShortString()                            + "; have you declared this activity in your AndroidManifest.xml?");                throw new ActivityNotFoundException(                        "No Activity found to handle " + intent);            case ActivityManager.START_PERMISSION_DENIED:                throw new SecurityException("Not allowed to start activity "                        + intent);            case ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT:                throw new AndroidRuntimeException(                        "FORWARD_RESULT_FLAG used while also requesting a result");            case ActivityManager.START_NOT_ACTIVITY:                throw new IllegalArgumentException(                        "PendingIntent is not an activity");            case ActivityManager.START_NOT_VOICE_COMPATIBLE:                throw new SecurityException(                        "Starting under voice control not allowed for: " + intent);            case ActivityManager.START_NOT_CURRENT_USER_ACTIVITY:                // Fail silently for this case so we don't break current apps.                // TODO(b/22929608): Instead of failing silently or throwing an exception,                // we should properly position the activity in the stack (i.e. behind all current                // user activity/task) and not change the positioning of stacks.                Log.e(TAG,                        "Not allowed to start background user activity that shouldn't be displayed"                        + " for all users. Failing silently...");                break;            default:                throw new AndroidRuntimeException("Unknown error code "                        + res + " when starting " + intent);        }    }

很明显可以看出,checkStartActivityResult()就是在检查启动Activity的结果。当无法正确地启动一个Activity时,这个方法会抛出异常。其中熟悉的一条就是”Unable to find explicit activity class; have you declared this activity in your AndroidManifest.xml?“
接着我们继续分析AMS的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);    }

startActivity()调用了startActivityAsUser(),然后Activity的启动过程又转移到了ActivityStackSupervisor的startActivityMayWait()。startActivityMayWait()中又调用了startActivityLocked(),startActivityLocked()调用了startActivityUncheckedLocked(),startActivityUncheckedLocked()调用了resumeTopActivitiesLocked(),resumeTopActivitiesLocked()又调用了ActivityStack的resumeTopActivityLocked()。这个时候启动过程已经从ActivityStackSupervisor转移到了ActivityStack。
然后resumeTopActivityLocked()调用了resumeTopActivityInnerLocked(),resumeTopActivityInnerLocked()调用了ActivityStackSupervisor的startSpecificActivityLocked()。这个时候启动过程又从ActivityStack转移到了ActivityStackSupervisor。然后startSpecificActivityLocked()调用了realStartActivityLocked()。realStartActivityLocked()中有这样一段代码:

            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的类型是IApplicationThread。IApplicationThread继承了IInterface:

/** * Base class for Binder interfaces.  When defining a new interface, * you must derive it from IInterface. */public interface IInterface{    /**     * Retrieve the Binder object associated with this interface.     * You must use this instead of a plain cast, so that proxy objects     * can return the correct result.     */    public IBinder asBinder();}

从IInterface的定义可知,IApplicationThread继承了它,所以是一个Binder类型的接口。阅读IApplicationThread的源码,可以发现其内部包含了大量启动、停止Activity的接口,此外还包含了启动和停止服务的接口。那么IApplicationThread的实现类是什么,答案就是ActivityThread的内部类ApplicationThread。ApplicationThread继承自ApplicationThreadNative,ApplicationThreadNative是一个抽象类继承自Binder并且实现了IApplicationThread。
绕了一圈,Activity的启动最终回到了ApplicationThread,ApplicationThread通过scheduleLaunchActivity()来启动Activity:

        // we use token to identify this activity without having to send the        // activity itself back to the activity manager. (matters more with ipc)        @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<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);        }

最后发送了一个消息,不断调用重载方法:

    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是一个H类型的成员变量,它继承了Handler:

    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 static final int SEND_RESULT             = 108;        public static final int DESTROY_ACTIVITY        = 109;        ……        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;                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;                case PAUSE_ACTIVITY:                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause");                    handlePauseActivity((IBinder)msg.obj, false, (msg.arg1&1) != 0, msg.arg2,                            (msg.arg1&2) != 0);                    maybeSnapshot();                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);                    break;                    ……                }        }    }

从H对”LAUNCH_ACTIVITY”的处理可以看到,Activity的启动过程又转移到了handleLaunchActivity()。handleLaunchActivity()又调用了performLaunchActivity(),performLaunchActivity()主要完成如下几件事:
1.从ActivityClientRecord中获取待启动的Activity的组件信息

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

2.通过Instrumentation的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);            }        }    public Activity newActivity(ClassLoader cl, String className,            Intent intent)            throws InstantiationException, IllegalAccessException,            ClassNotFoundException {        return (Activity)cl.loadClass(className).newInstance();    }

3.通过LoadedApk的makeApplication()创建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) {            if (!mActivityThread.mInstrumentation.onException(app, e)) {                throw new RuntimeException(                    "Unable to instantiate application " + appClass                    + ": " + e.toString(), e);            }        }        mActivityThread.mAllApplications.add(app);        mApplication = app;        if (instrumentation != null) {            try {                instrumentation.callApplicationOnCreate(app);            } catch (Exception e) {                if (!instrumentation.onException(app, e)) {                    throw new RuntimeException(                        "Unable to create application " + app.getClass().getName()                        + ": " + e.toString(), e);                }            }        }        // Rewrite the R 'constants' for all library apks.        SparseArray<String> packageIdentifiers = getAssets(mActivityThread)                .getAssignedPackageIdentifiers();        final int N = packageIdentifiers.size();        for (int i = 0; i < N; i++) {            final int id = packageIdentifiers.keyAt(i);            if (id == 0x01 || id == 0x7f) {                continue;            }            rewriteRValues(getClassLoader(), packageIdentifiers.valueAt(i), id);        }        return app;    }

从以上代码可以看出,如果Application已经被创建过了就不会被再创建了,这意味着一个应用只能有一个Application对象。Application对象的创建也是通过Instrumentation来完成的,同样通过类加载器来实现。Application对象创建完毕后,会调用Instrumentation的callApplicationOnCreate()来调用Application的onCreate():

    public void callApplicationOnCreate(Application app) {        app.onCreate();    }

4.创建ContextImpl对象并通过Activity的attach()来完成一些重要数据的初始化

                Context appContext = createBaseContextForActivity(r, activity);                CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());                Configuration config = new Configuration(mCompatConfiguration);                if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity "                        + r.activityInfo.name + " with config " + config);                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);

5.调用Instrumentation的callActivityOnCreate()来调用Activity的onCreate()

    /**     * Perform calling of an activity's {@link Activity#onCreate}     * method.  The default implementation simply calls through to that method.     *     * @param activity The activity being created.     * @param icicle The previously frozen state (or null) to pass through to onCreate().     */    public void callActivityOnCreate(Activity activity, Bundle icicle) {        prePerformCreate(activity);        activity.performCreate(icicle);        postPerformCreate(activity);    }    /**     * Perform calling of an activity's {@link Activity#onCreate}     * method.  The default implementation simply calls through to that method.     *  @param activity The activity being created.     * @param icicle The previously frozen state (or null) to pass through to     * @param persistentState The previously persisted state (or null)     */    public void callActivityOnCreate(Activity activity, Bundle icicle,            PersistableBundle persistentState) {        prePerformCreate(activity);        activity.performCreate(icicle, persistentState);        postPerformCreate(activity);    }
阅读全文
1 0