Android Activity的启动过程.doc_第1页
Android Activity的启动过程.doc_第2页
Android Activity的启动过程.doc_第3页
Android Activity的启动过程.doc_第4页
Android Activity的启动过程.doc_第5页
已阅读5页,还剩15页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Android Activity的启动过程Activity的启动过程真的很复杂,先看一张图大概了解一下,其中用灰色背景框起来的是在同一个类的方法,如下图:那接下来就从源码的角度来分析Activity的启动过程。当然是从Activity的startActivity方法开始的,Overridepublic void startActivity(Intent intent) this.startActivity(intent, null);使用this关键字调用 了startActivity方法的两个参数的重载。如下:Overridepublic void startActivity(Intent intent, Nullable Bundle options) if (options != null) startActivityForResult(intent, -1, options); else / Note we want to go through this call for compatibility with / applications that may have overridden the method. startActivityForResult(intent, -1); 不管怎样,都会调用startActivityForResult方法。并将intent传进。public void startActivityForResult(Intent intent, int requestCode) startActivityForResult(intent, requestCode, null);转到了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 /代码省略 先是判断mParent是否为空。那么mParent是什么呢?Activity中有一个isChild方法如下:/* Is this activity embedded inside of another activity? */public final boolean isChild() return mParent != null;从注释中可以知道mParent是一个ActivityGroup来的,可以嵌入子Activity的,这个我没用过。在我刚学Android的时候Fragment已经很流行了。 那我们回到startActivityForResult方法直接看到mParent = null的情况即可。可以看到内部调用了Instrumentation的execStartActivity方法,从字眼上看这个方法就是用来启动Activity的吧。这个execStartActivity方法的第二个参数mMainThread.getApplicationThread()。是一个ApplicationThread对象。ApplicationThread继承自ApplicationThreadNative,而ApplicationThreadNative继承自Binder并实现了IApplicationThread接口。也就是说ApplicationThread是一个Binder,而且是IApplicationThread的实现类,IApplicationThread接口有很多启动Activity,Service,注册广播等方法,很强大。那么他的实现类ApplicationThread就具备了这些功能。好,到这里先。那现在跟进看看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; /代码省略 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;看,从execStartActivity方法的参数列表也可以看出,刚才传进的ApplicationThread是一个Binder。 那么现在分析下execStartActivity方法的内部实现,找到了startActivity的字眼了,在try/catch代码块,这个从抛出的异常RemoteException,也可以推断是一个跨进程操作了。先不管。从try/catch代码块中可以看到ActivityManagerNative.getDefault()调用了startActivity的方法去启动Activity,返回了一个result结果,之后将result传进checkStartActivityResult方法,这个方法是用来检查Activity启动结果的,如下: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); /代码省略 Unable to find explicit activity class have you declared this activity in your AndroidManifest.xml? No Activity found to handle,从这些熟悉的异常信息我们可以知道,当没有在AndroidManifest注册Activity,到了checkStartActivityResult方法就会抛出异常。好,那现在回到刚才分析的ActivityManagerNative.getDefault()调用startActivity方法,现在不知道怎么跟踪源码了,因为我们不知道ActivityManagerNative.getDefault()是什么?ActivityManagerNative是一个抽象类来的,继承自Binder并实现了IActivityManager接口。而ActivirtManagerService是继承自ActivityManagerNative这个抽象类的,也就是说ActivirtManagerService是IActivityManager的实现类。那么我们先看到ActivityManagerNative的getDefault方法,/* * Retrieve the systems default/global activity manager. */static public IActivityManager getDefault() return gDefault.get();那么gDefault又是什么?private static final Singleton gDefault = new Singleton() 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; ;gDefault其实是一个单例类,接收泛型参数。有一个create方法。那么就看看这个Singleton单例类是什么样的。public abstract class Singleton private T mInstance; protected abstract T create(); public final T get() synchronized (this) if (mInstance = null) mInstance = create(); return mInstance; 如果泛型对象为空,就调用create方法创建,不为空则返回,那么我们现在看到刚才的create方法的实现就好了。 ServiceManager调用了getService方法,这是什么意思呢?这个不深入了,其实ServiceManager.getService(“activity”)返回的就是IActivityManager 的实现类ActivirtManagerService。 而ServiceManager的内部,使用了集合来存储各种系统服务,而这种用集合存储服务的方法也是一种单例模式。有兴趣的同学可以去探探究竟。那么ActivityManagerNative.getDefault()返回的是一个ActivirtManagerService,简称AMS。我们现在看到AMS的startActivity方法即可。Overridepublic 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();继续跟进startActivityAsUser方法Overridepublic 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字眼,在最后的return语句。可以看到,调用了ActivityStackSupervisor的startActivityMayWait方法来启动Activity,这时已经到了到了ActivityStackSupervisor类了。现在回忆下开篇看的那张描述Activity启动过程的图,思路会更清晰。那继续跟进。探探ActivityStackSupervisor的startActivityMayWait方法,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, boolean ignoreTargetSecurity, int userId, IActivityContainer iContainer, TaskRecord inTask) / Refuse possible leaked file descriptors if (intent != null & intent.hasFileDescriptors() throw new IllegalArgumentException(File descriptors passed in Intent); boolean componentSpecified = intent.getComponent() != null; / Dont modify the clients object! intent = new Intent(intent); /代码省略 int res = startActivityLocked(caller, intent, resolvedType, aInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode, callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags, options, ignoreTargetSecurity, componentSpecified, null, container, inTask); /代码省略 return res; 这个方法代码其实是很长的啊,总之会转到startActivityLocked方法。那我们继续看到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 ignoreTargetSecurity, boolean componentSpecified, ActivityRecord outActivity, ActivityContainer container, TaskRecord inTask) int err = ActivityManager.START_SUCCESS; /代码省略 ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage, intent, resolvedType, aInfo, mService.mConfiguration, resultRecord, resultWho, requestCode, componentSpecified, voiceSession != null, this, container, options);/代码省略 err = startActivityUncheckedLocked(r, sourceRecord, voiceSession, voiceInteractor, startFlags, true, options, inTask); if (err = 0; -displayNdx) final ArrayList 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;这里会调用ActivityStack的resumeTopActivityLocked方法,此时已经来到了ActivityStack了。final boolean resumeTopActivityLocked(ActivityRecord prev, Bundle options) if (mStackSupervisor.inResumeTopActivity) / Dont even start recursing. return false; boolean result = false; try / Protect against recursion. mStackSupervisor.inResumeTopActivity = true; if (mService.mLockScreenShown = ActivityManagerService.LOCK_SCREEN_LEAVING) mService.mLockScreenShown = ActivityManagerService.LOCK_SCREEN_HIDDEN; mService.updateSleepIfNeededLocked(); result = resumeTopActivityInnerLocked(prev, options); finally mStackSupervisor.inResumeTopActivity = false; return result;看到try代码块,调用了ActivityStack的resumeTopActivityInnerLocked方法,如下:private boolean resumeTopActivityInnerLocked(ActivityRecord prev, Bundle options) /代码省略 if (DEBUG_STATES) Slog.d(TAG_STATES, resumeTopActivityLocked: Restarting + next); mStackSupervisor.startSpecificActivityLocked(next, true, true); if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked(); return true;resumeTopActivityInnerLocked方法内部又会调用ActivityStackSupervisor的startSpecificActivityLocked方法,现在又回到了ActivityStackSupervisor。好神奇兜了一圈又回来了继续看到ActivityStackSupervisor的startSpecificActivityLocked方法void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) / Is this activitys application already running? ProcessRecord app = mService.getProcessRecordLocked(cessName, .applicationInfo.uid, true); r.task.stack.setLaunchTime(r); if (app != null & app.thread != null) try if (.flags&ActivityInfo.FLAG_MULTIPROCESS) = 0 | !android.equals(.packageName) / Dont 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 doesnt make sense to track as a / separate apk in the ocess. app.addPackage(.packageName, .applicationInfo.versionCode, mService.mProcessStats); realStartActivityLocked(r, app, andResume, checkConfig); return; catch (RemoteException e) Slog.w(TAG, Exception when starting activity + ent.getComponent().flattenToShortString(), e); / If a dead object exception was thrown - fall through to / restart the application. mService.startProcessLocked(cessName, .applicationInfo, true, 0, activity, ent.getComponent(), false, false, true);可以看到调用了realStartActivityLocked方法,这个方法已经开始将Activity的启动过程往AvtivityThread靠近了。那继续跟进realStartActivityLocked方法。final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app, boolean andResume, boolean checkConfig) throws RemoteException /代码省略 app.thread.scheduleLaunchActivity(new Intent(ent), r.appToken, System.identityHashCode(r

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论