Android 启动加载流程
程序员文章站
2022-03-23 23:01:26
零蚀前言前言这段时间我要开始封闭开发了,是项目的重构,最近还有些手上其他项目出现问题(公信部),所以熬夜的时间 越来越长,学习的时间越来越短,终于这个月中旬开始了996的加班模式(加班费也很OK,所以没什么好说的????????????),所以今天完成了手上一个小项目后才想起来有笔记 没有发。这里我发现首先我的framework的资料并不是 很好,所以这样学必定事半功倍,得不偿失 ,学习方法可能也没认真构思过,所以 我决定改变一下,这不是我想要的framework,并且源代码一点点啃...
零蚀
前言
-
前言
-
这段时间我要开始封闭开发了,是项目的重构,最近还有些手上其他项目出现问题(公信部),所以熬夜的时间 越来越长,学习的时间越来越短,终于这个月中旬开始了996的加班模式(加班费也很OK,所以没什么好说的????????????),所以今天完成了手上一个小项目后才想起来有笔记 没有发。
-
这里我发现首先我的framework的资料并不是 很好,所以这样学必定事半功倍,得不偿失 ,学习方法可能也没认真构思过,所以 我决定改变一下,这不是我想要的framework,并且源代码一点点啃也很耗时(空闲时候慢慢看吧),然后这里我准备 先放下framework的学习,先行开始新的课程《Android逆向工程》。这算是为三,五年计划开篇,嘿嘿。
-
最后的最后,加油少年,人生就这一次,要活出自己。
-
启动
-
Activity的启动
- 根据学习进度,我们先了解一下activity时如何启动的,因为之前我也是遇到一些和应用启动相关的问题,也希望这次能一探究竟, 启动对应的的类是
.../packages/apps/Launcher3/src/com/android/launcher3/Launcher.java
。这是我们点击应用图标的启动流程。
// 这里获取了保存启动请求的参数,这个应该是一种反序列化的过程 // 注释中也提出这是一种跨启动程序实例保存。 PendingRequestArgs requestArgs = savedState.getParcelable(RUNTIME_STATE_PENDING_REQUEST_ARGS); // 获取参数后,将里面的类提取出来 Intent intent = pendingArgs.getPendingIntent(); .... // 获取到手机的权限后,然后启动了activity if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { startActivitySafely(v, intent, null); } .... // 开启任务栈准备跳转 // Prepare intent intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // 最后进行跳转 .... startActivity(intent, optsBundle);
- 然后这里提示这个startActivity来自Activity.java , 然后我们看过去,大概是下面这个样子,
public 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); } } public void startActivityForResult(@RequiresPermission Intent intent, int requestCode, @Nullable Bundle options) { // 如果activity的父控件失是空的 if (mParent == null) { options = transferSpringboardActivityOptions(options); 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 { // Note we want to go through this method for compatibility with // existing applications that may have overridden it. mParent.startActivityFromChild(this, intent, requestCode); } } }
- 这里如果父控件为空,也就是说activity父类都还没有创建,这里就会启动一个
mInstrumentation.execStartActivity
,这个方法中定义了一个ActivityMonitor来监测应用程序和系统的交互。而这个方法,是调用了AMS(ActivityManager .getService ()
)AMS启动了它里面的startActivity。然后我们来看一下ActivityManagerService,这里面检查了一下启动权限,然后把任务交给了mActivityStarter
。
public final int startActivityAsUser(IApplicationThread caller, String callingPackage, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) { enforceNotIsolatedCaller("startActivity"); userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, false, ALLOW_FULL_ONLY, "startActivity", null); // TODO: Switch to user app stacks here. return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, null, null, bOptions, false, userId, null, null, "startActivityAsUser"); }
- 我们一直跟着返回值进行查找,在
startActivityUnchecked
方法中发现他是对activity的栈进行管理。然后这里调用失败会走ActivityOptions.abort(mOptions)
等方法,如果成功任务栈锁定activitymTargetStack.startActivityLocked
,当一切正常后进入resumeFocusedStackTopActivityLocked
这个方法里面调用了ActivityStack中的resumeTopActivityInnerLocked
- 这里我们继续看里面调用了
startSpecificActivityLocked
方法,这个start方法中又调用realStartActivityLocked
这个realstart
app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken, System.identityHashCode(r), r.info, // TODO: Have this take the merged configuration instead of separate global and // override configs. mergedConfiguration.getGlobalConfiguration(), mergedConfiguration.getOverrideConfiguration(), r.compat, r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle, r.persistentState, results, newIntents, !andResume, mService.isNextTransitionForward(), profilerInfo);
-
这里面调用的thread是
IApplicationThread
接口对象,这个对象在ApplicationThread extends IApplicationThread.Stub
调用,这个AcpplictionThread 是 ActivityThread 类所调用。这个scheduleLaunchActivity
方法的调用也是在ActivityThread中实现。 -
这里就相当于SystemServer进程中的AMS直接和应用进程中的ActicityThread进行了Binder通信。
- 根据学习进度,我们先了解一下activity时如何启动的,因为之前我也是遇到一些和应用启动相关的问题,也希望这次能一探究竟, 启动对应的的类是
本文地址:https://blog.csdn.net/qq_38315348/article/details/110259553
推荐阅读
-
Android开发实现ImageView加载摄像头拍摄的大图功能
-
解决android studio 3.0 加载项目过慢问题--maven仓库选择
-
mybatis延迟加载原理(mybatis工作原理及流程)
-
Android之Viewpager+Fragment实现懒加载示例
-
android WebView加载html5介绍
-
android判断phonegap是否联网且加载super.loadUrl网址
-
Android Intent启动别的应用实现方法
-
Android 加载大图及多图避免程序出现OOM(OutOfMemory)异常
-
android 定时启动\取消小例子
-
Android闹钟启动时间设置无效问题的解决方法