Android设计模式(四)续:Activity的onCreate是怎么调用的
2017-03-30 00:40
253 查看
原文地址 http://blog.csdn.net/qq_25806863/article/details/68288085
这里分析的是app第一次启动时的第一个Activity的onCreate()方法的启动流程。
其实通过这个代码我们可以发现一个有趣的现象,APP可以一直运行不会退出就因为这个main方法最后的
当一个APP启动的时候,系统会从Zygone线程中为应用fork一个新的线程,然后在线程中执行ActivityThread的main方法。
main方法中主要流程就是:
- 准备一个主线程的Looper
- 新建一个ActivityThread,并执行他的attach方法
- 开启Looper的loop方法开始无限循环的读取消息队列的消息 并处理。
ActivityManagerNative.getDefault()就是获取一个AMS,从下面的代码可以看到用的是单例模式从SystemManager中获取到。
这里 主要看两个方法,thread.bindApplication(……)方法和mStackSupervisor.attachApplicationLocked(app)。
ApplicationThread是ActivityThread的内部类,里面主要还是把这个ApplicationThread绑定到AMS中。
mStackSupervisor是一个ActivityStackSupervisor类,在AMS创建的时候初始化。
上面的方法里一大堆代码,主要就是检查准备要启动的Activity的信息,信息正常的话就执行 app.thread.scheduleLaunchActivity(…..)方法。
然后就又回到了ApplicationThread:
里面创建了一个ActivityClientRecord来保存activity的各种信息,然后放在消息里发送给H,消息的标识是H.LAUNCH_ACTIVITY,消息的内容就是这个ActivityClientRecord。
H也是ActivityThread的一个内部类:
这个handler接收到LAUNCH_ACTIVITY的信息后,会调用handleLaunchActivity(…)方法
继续
是不是终于看到了activity的方法,马上就到了
看到没,执行到了onCreate方法,还有一些生命周期的方法也是这样的逻辑,包括service和广播。
这里分析的是app第一次启动时的第一个Activity的onCreate()方法的启动流程。
图
先贴一下大致的流程图吧,不会画,很丑ActivityThread.main()
APP的启动入口应该都知道是ActivityThread的main方法了,所以整个APP的启动就从这里开始,直到我们看到首页。代码不多:package android.app; 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")); } Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); Looper.loop(); throw new RuntimeException("Main thread loop unexpectedly exited"); } }
其实通过这个代码我们可以发现一个有趣的现象,APP可以一直运行不会退出就因为这个main方法最后的
Looper.loop()是个死循环。
当一个APP启动的时候,系统会从Zygone线程中为应用fork一个新的线程,然后在线程中执行ActivityThread的main方法。
main方法中主要流程就是:
- 准备一个主线程的Looper
- 新建一个ActivityThread,并执行他的attach方法
- 开启Looper的loop方法开始无限循环的读取消息队列的消息 并处理。
ActivityThread.attach(false)
下面看一下ActivityThread.attach(),在main()中传入的参数是FALSE,说明这个APP不是系统APP。所以我们主要就看不是系统APP的处理。private void attach(boolean system) { sCurrentActivityThread = this; mSystemThread = system; if (!system) { //不是系统APP ViewRootImpl.addFirstDrawHandler(new Runnable() { @Override public void run() { //确定虚拟机正常 ensureJitEnabled(); } }); //.....略 //获取一个ActivityManagerService AMS final IActivityManager mgr = ActivityManagerNative.getDefault(); try { //mAppThread = new ApplicationThread(),绑定到AMS上 mgr.attachApplication(mAppThread); } catch (RemoteException ex) { throw ex.rethrowFromSystemServer(); } //......略 } else { //.....略 }
ActivityManagerNative.getDefault()就是获取一个AMS,从下面的代码可以看到用的是单例模式从SystemManager中获取到。
package android.app; public abstract class ActivityManagerNative extends Binder implements IActivityManager{ static public IActivityManager getDefault() { return gDefault.get(); } private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() { protected IActivityManager create() { //获取AMS 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; } }; }
(AMS)mgr.attachApplication()
package com.android.server.am; public final class ActivityManagerService extends ActivityManagerNative implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { @Override public final void attachApplication(IApplicationThread thread) { synchronized (this) { int callingPid = Binder.getCallingPid(); final long origId = Binder.clearCallingIdentity(); //执行AMS的这个方法 attachApplicationLocked(thread, callingPid); Binder.restoreCallingIdentity(origId); } } private final boolean attachApplicationLocked(IApplicationThread thread, int pid) { //......略 try { ProfilerInfo profilerInfo = profileFile == null ? null : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop); //执行了ApplicationThread的bindApplication方法 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()); //..... } catch (Exception e) { //...... } // 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) { } } return true; } }
这里 主要看两个方法,thread.bindApplication(……)方法和mStackSupervisor.attachApplicationLocked(app)。
ApplicationThread是ActivityThread的内部类,里面主要还是把这个ApplicationThread绑定到AMS中。
mStackSupervisor是一个ActivityStackSupervisor类,在AMS创建的时候初始化。
mStackSupervisor.attachApplicationLocked(app)
下面看他的方法package com.android.server.am; public final class ActivityStackSupervisor implements DisplayListener { 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 { //看这个方法就知道是真正启动一个Activity 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; } final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app, boolean andResume, boolean checkConfig) throws RemoteException { //这个传进来是true,所以一定会进去 if (andResume) { //冻结尚未启动的其他APP r.startFreezingScreenLocked(app, 0); mWindowManager.setAppVisibility(r.appToken, true); // 搜集启动比较慢的APP的信息 r.startLaunchTickingLocked(); } 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; } //... if (r.isHomeActivity()){ //如果是桌面的activity,就加到栈底 mService.mHomeProcess = task.mActivities.get(0).app; } //。。。。 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); } catch (RemoteException e) { } } return true; } }
上面的方法里一大堆代码,主要就是检查准备要启动的Activity的信息,信息正常的话就执行 app.thread.scheduleLaunchActivity(…..)方法。
然后就又回到了ApplicationThread:
ApplicationThread.scheduleLaunchActivity(…..)
package android.app; 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来保存activity的各种信息,然后放在消息里发送给H,消息的标识是H.LAUNCH_ACTIVITY,消息的内容就是这个ActivityClientRecord。
H也是ActivityThread的一个内部类:
ActivityThread.H
private class H extends Handler { public static final int LAUNCH_ACTIVITY = 100; public void handleMessage(Message msg) { 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, "LAUNCH_ACTIVITY"); Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); } break; } } }
这个handler接收到LAUNCH_ACTIVITY的信息后,会调用handleLaunchActivity(…)方法
ActivityThread.handleLaunchActivity(r, null, “LAUNCH_ACTIVITY”);
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) { //..... Activity a = performLaunchActivity(r, customIntent); //..... }
ActivityThread.performLaunchActivity(r, customIntent)
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) { //获取activity的信息 ActivityInfo aInfo = r.activityInfo; //...对信息进行一些判断 略 Activity activity = null; try { //通过反射获取到activity类 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); } } try { //获取application Application app = r.packageInfo.makeApplication(false, mInstrumentation); if (activity != null) { //生成activity的Context Context appContext = createBaseContextForActivity(r, activity); //....略 //将activity绑定到application 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); //...略 //调用callActivityOnCreate方法 if (r.isPersistable()) { mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState); } else { mInstrumentation.callActivityOnCreate(activity, r.state); } } } catch (SuperNotCalledException e) { } return activity; }
继续
Instrumentation.callActivityOnCreate
package android.app; public class Instrumentation { public void callActivityOnCreate(Activity activity, Bundle icicle) { prePerformCreate(activity); activity.performCreate(icicle); postPerformCreate(activity); } }
是不是终于看到了activity的方法,马上就到了
activity.performCreate(icicle);
package android.app; public class Activity extends ContextThemeWrapper implements LayoutInflater.Factory2, Window.Callback, KeyEvent.Callback, OnCreateContextMenuListener, ComponentCallbacks2, Window.OnWindowDismissedCallback, WindowControllerCallback { final void performCreate(Bundle icicle) { restoreHasCurrentPermissionRequest(icicle); onCreate(icicle); mActivityTransitionState.readState(icicle); performCreateCommon(); } }
看到没,执行到了onCreate方法,还有一些生命周期的方法也是这样的逻辑,包括service和广播。
相关文章推荐
- 关于Android的Activity的onCreate多次调用的问题
- android屏幕旋转时,Activity不重新调用onCreate的方法
- Android中一个Activity第二次启动时,onCreate()调用setContentView()方法时出错,程序崩溃
- Android屏幕旋转时,设置Activity不重新调用onCreate
- 怎么在service中调用activity中的handler
- 关于Android的Activity的onCreate多次调用的问题
- activity的onCreate里面调用getResources().getStringArray(int id)报错
- activity中onCreate没有调用setContentView,会如何展示?
- android屏幕旋转时Activity不重新调用onCreate的方法
- Android的Activity什么时候会调用onCreate()而不调用onStart()?
- Android的Activity的onCreate()多次调用的问题
- android 点击notification,跳转activity 时调用oncreate方法
- Activity oncreate调用多次问题
- activity启动模式,返回上一个activity时又调用一次onCreate()方法
- 关于Android的Activity的onCreate多次调用的问题
- 关于Android的Activity的onCreate多次调用的问题
- 屏幕旋转时阻止Activity自动调用Oncreate()方法
- Fragment怎么直接调用Activity的方法
- 简述Android中Activity的启动(onCreate方法的调用)
- OnNewIntent 的调用,SingleStask 单例模式的Activity 当遇到新的Intent的时候,不会走onCreate方法了