美文网首页《Android开发艺术探索》读书笔记与总结
《Android开发艺术探索》笔记2:重识Activity——A

《Android开发艺术探索》笔记2:重识Activity——A

作者: dev_journey | 来源:发表于2017-04-20 19:59 被阅读0次

    我们在日常开发中使用Activity很少去关注Activity的一些细节,那么现在我们就通过查看源码的方式,逐层点进去看看Activity启动的时候,系统都做了些什么,首先,我们启动Activity的代码是:

     Intent intent = new Intent(this, OtherActivity.class);
     startActivity(intent);
    

    从startActivity方法入手,点进去就到了Activity的源码,发现startActivity有好几个重载方法,但是最终都会调用同一个方法,就是startActivityForResult,有没有感觉很熟悉,我们在Activity返回时希望能获取到返回参数,就是调用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;
                }
    
                final View decor = mWindow != null ? mWindow.peekDecorView() : null;
                if (decor != null) {
                    decor.cancelPendingInputEvents();
                }
                // 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);
                }
            }
            if (options != null && !isTopOfTask()) {
                mActivityTransitionState.startExitOutTransition(this, options);
            }
        }
    

    上面的代码中,我们可以注意到一个参数mMainThread.getApplicationThread(),进一步点击去找到了,可以知道参数类型是ApplicationThread,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;
            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) {
            }
            return null;
        }
    

    上面代码具体细节不做分析,我也没咋看明白各个步骤都是做什么,但是后面发现启动Activity会交给ActivityManagerNative.getDefault()的startActivity方法去执行,先看看ActivityManagerNative。

    public abstract class ActivityManagerNative extends Binder implements IActivityManager
    public final class ActivityManagerService extends ActivityManagerNative
            implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback
    

    ActivityManagerService (AMS)继承自ActivityManagerNative,而ActivityManagerNative继承自Binder实现了IActivityManager这个Binder接口,因此AMS也是一个Binder,它是IActivityManager的具体实现,由于ActivityManagerNative.getDefault()返回的是IActivityManager的Binder对象,因为具体实现还需要查看AMS。在分析AMS的startActivity方法之前,先看看Instrumentation的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_VOICE_NOT_ACTIVE_SESSION:
                    throw new IllegalStateException(
                            "Session calling startVoiceActivity does not match active session");
                case ActivityManager.START_VOICE_HIDDEN_SESSION:
                    throw new IllegalStateException(
                            "Cannot start voice activity on a hidden session");
                case ActivityManager.START_CANCELED:
                    throw new AndroidRuntimeException("Activity could not be started for "
                            + intent);
                default:
                    throw new AndroidRuntimeException("Unknown error code "
                            + res + " when starting " + intent);
            }
        }
    

    比较有意思的是,这个方法就是检查Activity的结果,当无法正确返回一个Activity实例的时候,系统会抛出相对应的异常信息,例如最常见的"Unable to find explicit activity class; have you declared this activity in your AndroidManifest.xml?"未在清单中注册的Activity。下面就是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, userId, null, null);
        }
    

    上面代码中可以看到mStackSupervisor这个对象,实际上此时Activity调用又被传到ActivityStackSupervisor下的startActivityMyWait方法:

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

    接下来继续查看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);
    ...
    }
    

    继续查看startActivityUncheckedLocked方法:

        final int startActivityUncheckedLocked(ActivityRecord r, ActivityRecord sourceRecord,
                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags,
                boolean doResume, Bundle options, TaskRecord inTask) {
    ...
      if (doResume) {
                                resumeTopActivitiesLocked(targetStack, null, options);
                            } else {
                                ActivityOptions.abort(options);
                            }
    ...
    }
    

    查看resumeTopActivitiesLocked:

        boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target,
                Bundle targetOptions) {
            if (targetStack == null) {
                targetStack = getFocusedStack();
            }
            // Do targetStack first.
            boolean result = false;
            if (isFrontStack(targetStack)) {
                result = targetStack.resumeTopActivityLocked(target, targetOptions);
            }
            for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
                final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
                for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
                    final ActivityStack stack = stacks.get(stackNdx);
                    if (stack == targetStack) {
                        // Already started above.
                        continue;
                    }
                    if (isFrontStack(stack)) {
                        stack.resumeTopActivityLocked(null);
                    }
                }
            }
            return result;
        }
    

    可以看到最终启动过程从ActivityStackSupervisor转移到了ActivityStack中,下面是ActivityStack的resumeTopActivityLocked方法:

    final boolean resumeTopActivityLocked(ActivityRecord prev, Bundle options) {
            if (inResumeTopActivity) {
                // Don't even start recursing.
                return false;
            }
    
            boolean result = false;
            try {
                // Protect against recursion.
                inResumeTopActivity = true;
                result = resumeTopActivityInnerLocked(prev, options);
            } finally {
                inResumeTopActivity = false;
            }
            return result;
        }
    

    进一步调用了resumeTopActivityInnerLocked:

     final boolean resumeTopActivityInnerLocked(ActivityRecord prev, Bundle options) {
    ...
     mStackSupervisor.startSpecificActivityLocked(next, true, false);
    ...
    }
    

    这样在ActivityStack中的resumeTopActivityInnerLocked方法中又调用了ActivityStackSupervisor的startSpecificActivityLocked方法:

        void startSpecificActivityLocked(ActivityRecord r,
                boolean andResume, boolean checkConfig) {
            // Is this activity's application already running?
            ProcessRecord app = mService.getProcessRecordLocked(r.processName,
                    r.info.applicationInfo.uid, true);
    
            r.task.stack.setLaunchTime(r);
    
            if (app != null && app.thread != null) {
                try {
                    if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0
                            || !"android".equals(r.info.packageName)) {
                        // Don't add this if it is a platform component that is marked
                        // to run in multiple processes, because this is actually
                        // part of the framework so doesn't make sense to track as a
                        // separate apk in the process.
                        app.addPackage(r.info.packageName, r.info.applicationInfo.versionCode,
                                mService.mProcessStats);
                    }
                    realStartActivityLocked(r, app, andResume, checkConfig);
                    return;
                } catch (RemoteException e) {
                    Slog.w(TAG, "Exception when starting activity "
                            + r.intent.getComponent().flattenToShortString(), e);
                }
    
                // If a dead object exception was thrown -- fall through to
                // restart the application.
            }
    
            mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
                    "activity", r.intent.getComponent(), false, false, true);
        }
    

    在startSpecificActivityLocked方法中又调用了realStartActivityLocked方法,那么整个在ActivityStackSupervisor和ActivityStack之间的传递顺序用图表示如下:

    图1、ActivityStackSupervisor和ActivityStack之间的传递顺序

    再看一下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.task.voiceInteractor, app.repProcState, r.icicle, r.persistentState,
                        results, newIntents, !andResume, mService.isNextTransitionForward(),
                        profilerInfo);
    ...
    }
    

    app.thread的类型为IApplicationThread,IApplicationThread的类型声明如下:

    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<ResultInfo> results) throws RemoteException;
        void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
                ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo,
                IVoiceInteractor voiceInteractor, int procState, Bundle state,
                PersistableBundle persistentState, List<ResultInfo> pendingResults,
                List<Intent> pendingNewIntents, boolean notResumed, boolean isForward,
                ProfilerInfo profilerInfo) throws RemoteException;
        void scheduleRelaunchActivity(IBinder token, List<ResultInfo> pendingResults,
                List<Intent> pendingNewIntents, int configChanges,
                boolean notResumed, Configuration config) throws RemoteException;
        void scheduleNewIntent(List<Intent> intent, IBinder token) throws RemoteException;
        void scheduleDestroyActivity(IBinder token, boolean finished,
                int configChanges) throws RemoteException;
        void scheduleReceiver(Intent intent, ActivityInfo info, CompatibilityInfo compatInfo,
                int resultCode, String data, Bundle extras, boolean sync,
                int sendingUser, int processState) throws RemoteException;
        static final int BACKUP_MODE_INCREMENTAL = 0;
        static final int BACKUP_MODE_FULL = 1;
        static final int BACKUP_MODE_RESTORE = 2;
        static final int BACKUP_MODE_RESTORE_FULL = 3;
        void scheduleCreateBackupAgent(ApplicationInfo app, CompatibilityInfo compatInfo,
                int backupMode) throws RemoteException;
        void scheduleDestroyBackupAgent(ApplicationInfo app, CompatibilityInfo compatInfo)
                throws RemoteException;
        void scheduleCreateService(IBinder token, ServiceInfo info,
                CompatibilityInfo compatInfo, int processState) throws RemoteException;
        void scheduleBindService(IBinder token,
                Intent intent, boolean rebind, int processState) throws RemoteException;
        void scheduleUnbindService(IBinder token,
                Intent intent) throws RemoteException;
        void scheduleServiceArgs(IBinder token, boolean taskRemoved, int startId,
                int flags, Intent args) throws RemoteException;
        void scheduleStopService(IBinder token) throws RemoteException;
    ...
    }
    

    可以看到IApplicationThread继承了IInterface接口,它是一个Binder类型的接口,IApplicationThread里定义了很多启动,结束Activity和Service等等的方法,那么上面提到过IApplicationThread的实现类是ActivityThread中的内部类ApplicationThread,在ApplicationThread中通过scheduleLaunchActivity方法来启动activity:

    public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
                    ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo,
                    IVoiceInteractor voiceInteractor, int procState, Bundle state,
                    PersistableBundle persistentState, List<ResultInfo> pendingResults,
                    List<Intent> pendingNewIntents, boolean notResumed, boolean isForward,
                    ProfilerInfo profilerInfo) {
    
                updateProcessState(procState, false);
    
                ActivityClientRecord r = new ActivityClientRecord();
    
                r.token = token;
                r.ident = ident;
                r.intent = intent;
                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);
            }
    

    scheduleLaunchActivity方法其实很简单,就是发送一个启动activity的消息交给Handler处理,这个handler就是代码中的H。sendMessage方法如下:

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

    接下来Handler H的代码是这样的:

    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 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;
                 ...
                }
                if (DEBUG_MESSAGES) Slog.v(TAG, "<<< done: " + codeToString(msg.what));
            }
    ...
        }
    

    可以看到Handler H对“LAUNCH_ACTIVITY”这个消息的处理是,调用handleLaunchActivity方法来实现:

      private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
    ...
    if (localLOGV) Slog.v(
                TAG, "Handling launch of " + r);
    
            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);
    ...
    }
    ...  
    }
    

    上面源码可以看出,handleLaunchActivity最终也是调用performLaunchActivity来完成Activity的启动,并且ActivityThread通过handleResumeActivity方法调用被启动Activity的onResume这一生命周期方法。
    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);
                }
            }
    

    Instrumentation的newActivity比较简单,就是通过类加载器来创建Activity对象。

     public Activity newActivity(ClassLoader cl, String className,
                Intent intent)
                throws InstantiationException, IllegalAccessException,
                ClassNotFoundException {
            return (Activity)cl.loadClass(className).newInstance();
        }
    
    3,通过LoadApk的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来完成的,这个过程和Activity对象的创建一样,都是通过类加载器来实现的。Application创建完毕后,系统会通过Instrumentation的callApplicationOnCreate方法调用Application的onCreate方法。

    4,创建ComtextImpl对象并通过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.voiceInteractor);
    
    5,调用Activity的onCreate方法
      if (r.isPersistable()) {
          mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
       } else {
          mInstrumentation.callActivityOnCreate(activity, r.state);
       }
    

    通过Instrumentation调用callActivityOnCreat的方法,这样Activity的onCreate方法就执行了,此时Activity完成整个的启动流程。

    图2、activity启动过程流程图

    PS:感谢《Android开发艺术探索》,带我深入源码分析了Activity相关知识,这是一部很好的教程,希望小伙伴们购买正版书籍看一下,谢谢~

    相关文章

      网友评论

        本文标题:《Android开发艺术探索》笔记2:重识Activity——A

        本文链接:https://www.haomeiwen.com/subject/bjmlzttx.html