美文网首页Android技术知识Android知识Android开发
【Android源码】Activity是如何创建的,以及生命周期

【Android源码】Activity是如何创建的,以及生命周期

作者: 指间沙似流年 | 来源:发表于2017-05-31 09:36 被阅读108次

    我们在开发Android的过程中,都知道Activity调用的生命周期的第一个就是onCreate。而我们所学的Java中所讲的一个类的构造函数是首先被调用的,但是我们又极少在Activity中涉及到构造函数,而是只需要关注生命周期就可以了。

    我们经常认为的app的启动就是Activity的启动,而实际上并不是这样,对于一个app来说,真正的入口是ActivityThread:

    public final class ActivityThread {
        public static void main(String[] args) {
            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");
            SamplingProfilerIntegration.start();
    
            CloseGuard.setEnabled(false);
    
            Environment.initForCurrentUser();
    
            EventLogger.setReporter(new EventLoggingReporter());
    
            final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
            TrustedCertificateStore.setDefaultUserDirectory(configDir);
    
            Process.setArgV0("<pre-initialized>");
    
            Looper.prepareMainLooper();
    
            ActivityThread thread = new ActivityThread();
            thread.attach(false);
    
            if (sMainThreadHandler == null) {
                sMainThreadHandler = thread.getHandler();
            }
    
            if (false) {
                Looper.myLooper().setMessageLogging(new
                        LogPrinter(Log.DEBUG, "ActivityThread"));
            }
    
            // End of event ActivityThreadMain.
            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
            Looper.loop();
    
            throw new RuntimeException("Main thread loop unexpectedly exited");
        }
    }
    

    可以发现ActivityThread类是一个final类,表明这个类是不能被继承的,一个app对应一个ActivityThread。当Zygote进程孵化一个新的app的时候,会执行ActivityThread的main方法。
    main方法中则是执行了大量的初始化工作,比如主线程的Handler、Looper,并调用thread.attach(false)绑定到ActivityManagerService上,之后就开始不断的读取消息队列并分发。
    我们在观察attach方法,其中false表示非系统应用:

    private void attach(boolean system) {
       sCurrentActivityThread = this;
       mSystemThread = system;
       if (!system) {
           ViewRootImpl.addFirstDrawHandler(new Runnable() {
               @Override
               public void run() {
                   ensureJitEnabled();
               }
           });
           android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",
                                                   UserHandle.myUserId());
           RuntimeInit.setApplicationObject(mAppThread.asBinder());
           final IActivityManager mgr = ActivityManagerNative.getDefault();
           try {
               mgr.attachApplication(mAppThread);
           } catch (RemoteException ex) {
               throw ex.rethrowFromSystemServer();
           }
       } else {
       }
    }
    

    这个方法中我们主要关注mgr.attachApplication(mAppThread)方法,可以发现将ActivityThread绑定到了ActivityManagerService中:

    @Override
    public final void attachApplication(IApplicationThread thread) {
       synchronized (this) {
           int callingPid = Binder.getCallingPid();
           final long origId = Binder.clearCallingIdentity();
           attachApplicationLocked(thread, callingPid);
           Binder.restoreCallingIdentity(origId);
       }
    }
    private final boolean attachApplicationLocked(IApplicationThread thread,
           int pid) {
        // 将ApplicationThread绑定到ActivityManagerService
        thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
                        profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
                        app.instrumentationUiAutomationConnection, testMode,
                        mBinderTransactionTrackingEnabled, enableTrackAllocation,
                        isRestrictedBackupMode || !normalMode, app.persistent,
                        new Configuration(mConfiguration), app.compat,
                        getCommonServicesLocked(app.isolated),
                        mCoreSettingsObserver.getCoreSettingsLocked());
                        
        // See if the top visible activity is waiting to run in this process...
       if (normalMode) {
           try {
               if (mStackSupervisor.attachApplicationLocked(app)) {
                   didSomething = true;
               }
           } catch (Exception e) {
               Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
               badApp = true;
           }
       }  
    }
    
    boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {
       final String processName = app.processName;
       boolean didSomething = false;
       for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
           ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
           for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
               final ActivityStack stack = stacks.get(stackNdx);
               if (!isFocusedStack(stack)) {
                   continue;
               }
               ActivityRecord hr = stack.topRunningActivityLocked();
               if (hr != null) {
                   if (hr.app == null && app.uid == hr.info.applicationInfo.uid
                           && processName.equals(hr.processName)) {
                       try {
                           if (realStartActivityLocked(hr, app, true, true)) {
                               didSomething = true;
                           }
                       } catch (RemoteException e) {
                           Slog.w(TAG, "Exception in new application when starting activity "
                                 + hr.intent.getComponent().flattenToShortString(), e);
                           throw e;
                       }
                   }
               }
           }
       }
       if (!didSomething) {
           ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
       }
       return didSomething;
    }
    

    通过注释可以发现是通过mStackSupervisor.attachApplicationLocked(app)来找到当前进程的最顶上的可见Activity,之后通过方法内的realStartActivityLocked(hr, app, true, true)来处理真正启动Activity的逻辑:

    final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
           boolean andResume, boolean checkConfig) throws RemoteException {
            
       if (andResume) {
           // 冻结尚未启动的Activity
           r.startFreezingScreenLocked(app, 0);
            // 给WindowManager设置token,标识当前的App要在前台显示
           mWindowManager.setAppVisibility(r.appToken, true);
           // schedule launch ticks to collect information about slow apps.
           r.startLaunchTickingLocked();
       }
    
       // 检查配置信息
       if (checkConfig) {
           Configuration config = mWindowManager.updateOrientationFromAppTokens(
                   mService.mConfiguration,
                   r.mayFreezeScreenLocked(app) ? r.appToken : null);
           mService.updateConfigurationLocked(config, r, false);
       }
            // 设置参数
       r.app = app;
       app.waitingToKill = null;
       r.launchCount++;
       r.lastLaunchTime = SystemClock.uptimeMillis();
    
       int idx = app.activities.indexOf(r);
       if (idx < 0) {
           app.activities.add(r);
       }
       mService.updateLruProcessLocked(app, true, null);
       mService.updateOomAdjLocked();
    
       final TaskRecord task = r.task;
       final ActivityStack stack = task.stack;
       try {
           if (app.thread == null) {
               throw new RemoteException();
           }
           List<ResultInfo> results = null;
           List<ReferrerIntent> newIntents = null;
           if (andResume) {
               results = r.results;
               newIntents = r.newIntents;
           }
           // 如果是桌面,将其添加到Activity栈的底部
           if (r.isHomeActivity()) {
               // Home process is the root process of the task.
               mService.mHomeProcess = task.mActivities.get(0).app;
           }
           mService.notifyPackageUse(r.intent.getComponent().getPackageName(),
                                     PackageManager.NOTIFY_PACKAGE_USE_ACTIVITY);
           r.sleeping = false;
           r.forceNewConfig = false;
           mService.showUnsupportedZoomDialogIfNeededLocked(r);
           mService.showAskCompatModeDialogLocked(r);
           r.compat = mService.compatibilityInfoForPackageLocked(r.info.applicationInfo);
           ProfilerInfo profilerInfo = null;
           if (mService.mProfileApp != null && mService.mProfileApp.equals(app.processName)) {
               if (mService.mProfileProc == null || mService.mProfileProc == app) {
                   mService.mProfileProc = app;
                   final String profileFile = mService.mProfileFile;
                   if (profileFile != null) {
                       ParcelFileDescriptor profileFd = mService.mProfileFd;
                       if (profileFd != null) {
                           try {
                               profileFd = profileFd.dup();
                           } catch (IOException e) {
                               if (profileFd != null) {
                                   try {
                                       profileFd.close();
                                   } catch (IOException o) {
                                   }
                                   profileFd = null;
                               }
                           }
                       }
    
                       profilerInfo = new ProfilerInfo(profileFile, profileFd,
                               mService.mSamplingInterval, mService.mAutoStopProfiler);
                   }
               }
           }
    
           if (andResume) {
               app.hasShownUi = true;
               app.pendingUiClean = true;
           }
           app.forceProcessStateUpTo(mService.mTopProcessState);
    
           // 当所有的参数配置好之后,就准备启动Activity  
           app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
                   System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration),
                   new Configuration(task.mOverrideConfig), r.compat, r.launchedFromPackage,
                   task.voiceInteractor, app.repProcState, r.icicle, r.persistentState, results,
                   newIntents, !andResume, mService.isNextTransitionForward(), profilerInfo);
    
           if ((app.info.privateFlags&ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) != 0) {
               if (app.processName.equals(app.info.packageName)) {
                   if (mService.mHeavyWeightProcess != null
                           && mService.mHeavyWeightProcess != app) {
                       Slog.w(TAG, "Starting new heavy weight process " + app
                               + " when already running "
                               + mService.mHeavyWeightProcess);
                   }
                   mService.mHeavyWeightProcess = app;
                   Message msg = mService.mHandler.obtainMessage(
                           ActivityManagerService.POST_HEAVY_NOTIFICATION_MSG);
                   msg.obj = r;
                   mService.mHandler.sendMessage(msg);
               }
           }
    
       } catch (RemoteException e) {
           if (r.launchFailed) {
               // This is the second time we failed -- finish activity
               // and give up.
               Slog.e(TAG, "Second failure launching "
                     + r.intent.getComponent().flattenToShortString()
                     + ", giving up", e);
               mService.appDiedLocked(app);
               stack.requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null,
                       "2nd-crash", false);
               return false;
           }
    
           // This is the first time we failed -- restart process and
           // retry.
           app.activities.remove(r);
           throw e;
       }
    
       r.launchFailed = false;
       if (stack.updateLRUListLocked(r)) {
           Slog.w(TAG, "Activity " + r + " being launched, but already in LRU list");
       }
    
       if (andResume) {
           // As part of the process of launching, ActivityThread also performs
           // a resume.
           stack.minimalResumeActivityLocked(r);
       } else {
           if (DEBUG_STATES) Slog.v(TAG_STATES,
                   "Moving to PAUSED: " + r + " (starting in paused state)");
           r.state = PAUSED;
       }
       if (isFocusedStack(stack)) {
           mService.startSetupActivityLocked();
       }
       if (r.app != null) {
           mService.mServices.updateServiceConnectionActivitiesLocked(r.app);
       }
    
       return true;
    }
    

    realStartActivityLocked方法首先会配置启动Activity的各种参数,之后再调用ApplicationThread的scheduleLaunchActivity方法准备启动Activity:

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

    可以发现这个方法其实就是准备启动的信息,构造了ActivityClientRecord,并最终通过sendMessage(H.LAUNCH_ACTIVITY, r)发送启动消息给消息队列,给ActivityThread内的继承了Handler的子类H来处理。

    private class H extends Handler {
        public void handleMessage(Message msg) {
              case LAUNCH_ACTIVITY: {
                  final ActivityClientRecord r = (ActivityClientRecord) msg.obj;
        
                  r.packageInfo = getPackageInfoNoCheck(
                          r.activityInfo.applicationInfo, r.compatInfo);
                  handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");
              } break;
        }
    }
    
    private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
       Activity a = performLaunchActivity(r, customIntent);
    }
    

    最终调用performLaunchActivity来处理Activity的启动流程:

    private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
        // 获取ActivityInfo
       ActivityInfo aInfo = r.activityInfo;
       // 获取PackageInfo
       if (r.packageInfo == null) {
           r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
                   Context.CONTEXT_INCLUDE_CODE);
       }
        // 获取Intent传递的ComponentName
       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 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) {
       }
    
       try {
            // 获取Application
           Application app = r.packageInfo.makeApplication(false, mInstrumentation);
    
           if (activity != null) {
               Context appContext = createBaseContextForActivity(r, activity);
               // 将application、window、context绑定到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, window);
    
               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;
               // 调用oncreate方法
               if (r.isPersistable()) {
                   mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
               } else {
                   mInstrumentation.callActivityOnCreate(activity, r.state);
               }
           }
           r.paused = true;
    
           mActivities.put(r.token, r);
    
       } catch (Exception e) {
       }
    
       return activity;
    }
    

    这个方法主要用来处理Activity的启动逻辑:

    1. 获取ActivityInfo、PackageInfo、intent的ComponentName、Context、Window
    2. 通过反射构造Activity
    3. 将上面构造的随想绑定到Activity中
    4. 调用callActivityOnCreate方法
    public void callActivityOnCreate(Activity activity, Bundle icicle) {
       prePerformCreate(activity);
       activity.performCreate(icicle);
       postPerformCreate(activity);
    }
    
    // Activity.java
    final void performCreate(Bundle icicle) {
       restoreHasCurrentPermissionRequest(icicle);
       onCreate(icicle);
       mActivityTransitionState.readState(icicle);
       performCreateCommon();
    }
    

    最终通过performCreate方法,我们看到了我们所熟悉的onCreate方法,这个时候就走到了我们的生命周期方法中。
    当然其他的生命周期方法也可以通过类似的方式来找到调用逻辑。

    相关文章

      网友评论

        本文标题:【Android源码】Activity是如何创建的,以及生命周期

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