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

我们在开发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方法,这个时候就走到了我们的生命周期方法中。
当然其他的生命周期方法也可以通过类似的方式来找到调用逻辑。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,242评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,769评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,484评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,133评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,007评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,080评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,496评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,190评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,464评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,549评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,330评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,205评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,567评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,889评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,160评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,475评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,650评论 2 335

推荐阅读更多精彩内容