深入理解Activity进阶系列(一):Activity启动
来源:互联网 发布:白金数据txt 编辑:程序博客网 时间:2024/06/05 19:39
深入理解Activity进阶系列(一):Activity启动
本系列主要讲解Activity的一些进阶知识,大部分是通过源码分析了解Activity有关的内容,同时也会介绍一些平时比较不容易注意到的细节。
1. 深入理解Activity进阶系列(一):Activity启动
2. 深入理解Activity进阶系列(二):界面创建
……
本文主要讲解Activity启动过程,通过源码分比析较直观的展示了启动过程中具体做了什么事,并可以从中窥探Framewokr层几个重要的对象。
启动流程
Activity
从Activity的 public void startActivity(Intent intent) 入手分析,startActivity调用startActivityForResult(@RequiresPermission Intent intent, int requestCode,
@Nullable Bundle options)。startActivityForResult主要通过调用mInstrumentation的execStartActivity,执行启动操作。
这里稍微介绍一下mInstrumentation,是一个Instrumentation对象。
Instrumentation是执行application instrumentation代码的基类。当应用程序运行的时候instrumentation处于开启,Instrumentation将在任何应用程序运行前初始化,可以通过它监测系统与应用程序之间的交互。
Instrumentation似乎有些类似与window中的“钩子(Hook)函数”,在系统与应用程序之间安装了个“窃听器”。
一些插件化框架也是通过Instrumentation hook。
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode, @Nullable Bundle options) {// mParent顾名思义是当前Activity的父Activit,比如在使用//TabActivity会赋值。官方推荐使用Fragment,所以此处直接分析mParent == null的情况即可 if (mParent == null) { options = transferSpringboardActivityOptions(options); // 调用mInstrumentation.execStartActivity执行启动操作 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) { mStartedActivity = true; } cancelInputsAndStartExitTransition(options); } else { // 忽略 if (options != null) { mParent.startActivityFromChild(this, intent, requestCode, options); } else { mParent.startActivityFromChild(this, intent, requestCode); } } }
Instrumentation的execStartActivity主要就是调用ActivityManagerNative.getDefault()的startActivityAsUser执行启动,那ActivityManagerNative和getDefault()具体是什么呢?
public abstract class ActivityManagerNative extends Binder implements IActivityManager
public interface IActivityManager extends IInterface
从中可以看出ActivityManagerNative是一个Binder类,Activity的启动已经通过Binder调用转交到系统服务中了。
IActivityManager Binder具体实现是ActivityManagerService,最终调用到ActivityManagerService的startActivityAsUser
调用进入ActivityManagerService的进程
Instrumentation
public ActivityResult execStartActivity( Context who, IBinder contextThread, IBinder token, String target, Intent intent, int requestCode, Bundle options) { IApplicationThread whoThread = (IApplicationThread) contextThread; ... // 监控该Intent是否在启动,命中返回 try { intent.migrateExtraStreamToClipData(); intent.prepareToLeaveProcess(who); // 调用ActivityManagerNative.getDefault() .startActivityAsUser 启动Activity int result = ActivityManagerNative.getDefault() .startActivity(whoThread, who.getBasePackageName(), intent, intent.resolveTypeIfNeeded(who.getContentResolver()), token, target, requestCode, 0, null, options); // 检查启动Activity是否合法,比如Activity是否在AndroidManifest注册 checkStartActivityResult(result, intent); } catch (RemoteException e) { throw new RuntimeException("Failure from system", e); } return null; }
ActivityManagerService
ActivityManagerService的startActivityAsUser方法又调用了mStackSupervisor的 startActivityMayWait,mStackSupervisor是一个StackSupervisor对象。
ActivityStackSupervisor管理Activity栈
每一个ActivityRecord都会有一个Activity与之对应,一个Activity可能会有多个ActivityRecord,因为Activity可以被多次实例化,取决于其launchmode。一系列相关的ActivityRecord组成了一个TaskRecord,TaskRecord是存在于ActivityStack中,ActivityStackSupervisor是用来管理这些ActivityStack的。
@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) { ... // 调用mStackSupervisor.startActivityMayWait return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, null, null, options, false, userId, null, null); }
ActivityStackSupervisor
执行到ActivityStackSupervisor的时候,在startActivityMayWait中进行了一系列的方法调用,最终调用ActivityStack的resumeTopActivityLocked方法
ActivityStack
每一个ActivityRecord都会有一个Activity与之对应,一个Activity可能会有多个ActivityRecord,因为Activity可以被多次实例化,取决于其launchmode。一系列相关的ActivityRecord组成了一个TaskRecord,TaskRecord是存在于ActivityStack中,ActivityStackSupervisor是用来管理这些ActivityStack的。
- 调用ActivityStackSupervisor的startActivityMayWait
- startActivityMayWait调用startActivityLocked
- startActivityLocked调用startActivityUncheckedLocked
- startActivityUncheckedLocked调用resumeTopActivitiesLocked
- resumeTopActivitiesLocked调用ActivityStack的resumeTopActivityLocked
ActivityStack
ActivityStack的resumeTopActivityLocked又调用回ActivityStackSupervisor中的startSpecificActivityLocked
ActivityStackSupervisor
ActivityStackSupervisor的startSpecificActivityLocked调用了realStartActivityLocked,而 realStartActivityLocked最终调用了app.thread.scheduleLaunchActivity
IApplicationThread thread;
public interface IApplicationThread extends IInterface
public abstract class ApplicationThreadNative extends Binder implements IApplicationThread
ApplicationThreadNative的具体实现是ActivityThread中的ApplicationThread
ApplicationThread实现了许多Activity和Service 启动、暂停等有关的操作
调用进入应用程序的进程
final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app, boolean andResume, boolean checkConfig) throws RemoteException { ... // 调用了app.thread.scheduleLaunchActivity 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); ... return true; }
ApplicationThread
ApplicationThread的scheduleLaunchActivity通过mH发送了一条H.LAUNCH_ACTIVITY消息,mH是一个H对象,H是一个Handle。
final H mH = new H();
private class H extends Handler
H是一个Handler,封装了一些对Activity、Service等的处理消息具体操作
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) { ... // 更新一些状态和信息 // 发送LAUNCH_ACTIVITY消息 sendMessage(H.LAUNCH_ACTIVITY, r); }
private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) { Message msg = Message.obtain(); msg.what = what; msg.obj = obj; msg.arg1 = arg1; msg.arg2 = arg2; if (async) { msg.setAsynchronous(true); } mH.sendMessage(msg); }
mH收到LAUNCH_ACTIVITY消息时调用handleLaunchActivity
case LAUNCH_ACTIVITY: { // 调用ActivityThread的handleLaunchActivity handleLaunchActivity(r, null); } break;
handleLaunchActivity先通过performLaunchActivity创建相应的Activity,如果调用handleResumeActivity设置相关的界面等
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) { ... // 1.调用ActivityThread的performLaunchActivity Activity a = performLaunchActivity(r, customIntent); if (a != null) { ... // 2.调用ActivityThread的handleResumeActivity handleResumeActivity(r.token, false, r.isForward, !r.activity.mFinished && !r.startsNotResumed); ... } else { ... } }
ActivityThread的performLaunchActivity做了许多事情,可以说是Activity启动流程最主要的一步了, 具体内容见代码注释。
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent){ Activity activity = null; try { // 获取类加载器 java.lang.ClassLoader cl = r.packageInfo.getClassLoader(); // 调用Instrumentation的newActivity 实例化Activity activity = mInstrumentation.newActivity( cl, component.getClassName(), r.intent); ... } catch (Exception e) { } try { // 调用LoadedApk的makeApplication获取Application, //如果没有则创建,创建Application会创建一个ContextImpl,并赋值给Application的mBase, //创建成功调用Application,具体下面会分析 Application app = r.packageInfo.makeApplication(false, mInstrumentation); if (activity != null) { // 调用了ContextImpl.createActivityContext 创建了ContextImpl的实例 Context appContext = createBaseContextForActivity(r, activity); // 调用Activity的attach,将之前的创建的ContextImpl实例赋值给Activity的mBase, // 以及Window的创建和界面的加载,具体之后(第二篇)会详细分析 // 注意此时才将mBase赋值,之前Activity已经实例化,但mBase还未赋值 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); ... if (r.isPersistable()) { // callActivityOnCreate会调用Activity的performCreate, // Activity的postPerformCreate会调用Activity的onCreate方法 mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState); } else { mInstrumentation.callActivityOnCreate(activity, r.state); } if (!r.activity.mFinished) { // 调用Activity的performStart方法,之后会执行Activity的onStart()方法 activity.performStart(); r.stopped = false; } ... } // final ArrayMap<IBinder, ActivityClientRecord> mActivities = // new ArrayMap<>(); mActivities.put(r.token, r); } return activity; }
尝试创建Application是通过packageInfo创建的,packageInfo是一个LoadedApk。
LoadedApk
Local state maintained about a currently loaded .apk.LoadedApk对象是APK文件在内存中的表示。 Apk文件的相关信息,诸如Apk文件的代码和资源,甚至代码里面的Activity,Service、Receiver等组件的信息我们都可以通过此对象获取。
Activity创建之后调用了ActivityThread的handleResumeActivity,之后会调用Activity的onResume()方法。从这里可以大概看出Activity界面还没有显示出来的时候就调用了onResume方法,具体流程详见Activity启动流程源码分析(二):界面创建
总结
- 深入理解Activity进阶系列(一):Activity启动
- 深入理解Activity进阶系列(二):界面创建
- Activity深入理解(一)
- 深入理解Activity启动流程
- 深入理解Activity启动模式
- 深入理解Activity启动流程
- 深入理解Activity启动流程
- 深入理解Activity启动流程
- 深入理解Activity生命周期(一)
- 深入理解Activity启动流程(一)–Activity启动的概要流程
- 深入理解Activity启动流程(一)–Activity启动的概要流程
- 深入理解Activity启动流程(一)–Activity启动的概要流程
- Android进阶系列2-Activity启动模式
- 深入理解Activity启动模式(一)–Activity与进程,线程的关系
- 带你深入理解Activity启动模式(LaunchMode)
- AMS—启动一个Activity(基于深入理解Android)
- Activity生命周期及启动模式深入理解
- 深入理解Activity-任务,回退栈,启动模式
- Jzoj4731 游戏(待填)
- 【JAVA_SE】作业练习1021
- [笔记]有上下界的网络流笔记
- 贪心法 部分背包问题 结构体数组 FatMouse' Trade
- Set接口源码解析
- 深入理解Activity进阶系列(一):Activity启动
- webdriver 多窗口切换
- 通过鼠标的移动让图片移动
- render_to_response() got an unexpected keyword argument 'context_instance'
- HTTP的长连接和短连接
- 案例分析Java语言中try-catch-finally过程
- applicationWillEnterForeground 方法在切回后台后点击 App Icon 切回前台没有回调
- 2017-2018 ACM-ICPC, NEERC, Southern Subregional Contest E. Field of Wonders
- 【关于电脑】