靠着这份190页的面试资料,源码解析StartActivity的过程,膜拜

  1. r.autoStopProfiler = autoStopProfiler;

  2. updatePendingConfiguration(curConfig);

  3. queueOrSendMessage(H.LAUNCH_ACTIVITY, r);

  4. }

说明:上述代码很好理解,构造一个activity记录,然后发送一个消息,所以,我们要看看Handler是如何处理这个消息的,现在转到这个Handler,它有个很短的名字叫做H

code:ActivityThread#H

[java]  view plain copy 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  1. //这个类太长,我只帖出了我们用到的部分

  2. private class H extends Handler {

  3. public void handleMessage(Message msg) {

  4. if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));

  5. switch (msg.what) {

  6. //这里处理LAUNCH_ACTIVITY消息类型

  7. case LAUNCH_ACTIVITY: {

  8. Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, “activityStart”);

  9. ActivityClientRecord r = (ActivityClientRecord)msg.obj;

  10. r.packageInfo = getPackageInfoNoCheck(

  11. r.activityInfo.applicationInfo, r.compatInfo);

  12. //这里处理startActivity消息

  13. handleLaunchActivity(r, null);

  14. Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);

  15. } break;

  16. case RELAUNCH_ACTIVITY: {

  17. Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, “activityRestart”);

  18. ActivityClientRecord r = (ActivityClientRecord)msg.obj;

  19. handleRelaunchActivity®;

  20. Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);

  21. } break;

  22. case PAUSE_ACTIVITY:

  23. Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, “activityPause”);

  24. handlePauseActivity((IBinder)msg.obj, false, msg.arg1 != 0, msg.arg2);

  25. maybeSnapshot();

  26. Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);

  27. break;

  28. }

  29. }

说明:看来还要看handleLaunchActivity

code:ActivityThread#handleLaunchActivity

[java]  view plain copy 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  1. private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {

  2. // If we are getting ready to gc after going to the background, well

  3. // we are back active so skip it.

  4. unscheduleGcIdler();

  5. if (r.profileFd != null) {

  6. mProfiler.setProfiler(r.profileFile, r.profileFd);

  7. mProfiler.startProfiling();

  8. mProfiler.autoStopProfiler = r.autoStopProfiler;

  9. }

  10. // Make sure we are running with the most recent config.

  11. handleConfigurationChanged(null, null);

  12. if (localLOGV) Slog.v(

  13. TAG, "Handling launch of " + r);

  14. //终于到底了,大家都有点不耐烦了吧,从方法名可以看出,

  15. //performLaunchActivity真正完成了activity的调起,

  16. //同时activity会被实例化,并且onCreate会被调用

  17. Activity a = performLaunchActivity(r, customIntent);

  18. if (a != null) {

  19. r.createdConfig = new Configuration(mConfiguration);

  20. Bundle oldState = r.state;

  21. //看到没,目标activity的onResume会被调用

  22. handleResumeActivity(r.token, false, r.isForward,

  23. !r.activity.mFinished && !r.startsNotResumed);

  24. if (!r.activity.mFinished && r.startsNotResumed) {

  25. // The activity manager actually wants this one to start out

  26. // paused, because it needs to be visible but isn’t in the

  27. // foreground.  We accomplish this by going through the

  28. // normal startup (because activities expect to go through

  29. // onResume() the first time they run, before their window

  30. // is displayed), and then pausing it.  However, in this case

  31. // we do -not- need to do the full pause cycle (of freezing

  32. // and such) because the activity manager assumes it can just

  33. // retain the current state it has.

  34. try {

  35. r.activity.mCalled = false;

  36. //同时,由于新activity被调起了,原activity的onPause会被调用

  37. mInstrumentation.callActivityOnPause(r.activity);

  38. // We need to keep around the original state, in case

  39. // we need to be created again.  But we only do this

  40. // for pre-Honeycomb apps, which always save their state

  41. // when pausing, so we can not have them save their state

  42. // when restarting from a paused state.  For HC and later,

  43. // we want to (and can) let the state be saved as the normal

  44. // part of stopping the activity.

  45. if (r.isPreHoneycomb()) {

  46. r.state = oldState;

  47. }

  48. if (!r.activity.mCalled) {

  49. throw new SuperNotCalledException(

  50. "Activity " + r.intent.getComponent().toShortString() +

  51. " did not call through to super.onPause()");

  52. }

  53. } catch (SuperNotCalledException e) {

  54. throw e;

  55. } catch (Exception e) {

  56. if (!mInstrumentation.onException(r.activity, e)) {

  57. throw new RuntimeException(

  58. "Unable to pause activity "

  59. + r.intent.getComponent().toShortString()

  60. + ": " + e.toString(), e);

  61. }

  62. }

  63. r.paused = true;

  64. }

  65. } else {

  66. // If there was an error, for any reason, tell the activity

  67. // manager to stop us.

  68. try {

  69. ActivityManagerNative.getDefault()

  70. .finishActivity(r.token, Activity.RESULT_CANCELED, null);

  71. } catch (RemoteException ex) {

  72. // Ignore

  73. }

  74. }

  75. }

说明:关于原activity和新activity之间的状态同步,如果大家感兴趣可以自己研究下,因为逻辑太复杂,我没法把所有问题都说清楚,否则就太深入细节而淹没了整体逻辑,研究源码要的就是清楚整体逻辑。下面看最后一个方法,这个方法是activity的启动过程的真正实现。

code:ActivityThread#performLaunchActivity

[java]  view plain copy 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  1. private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {

  2. // System.out.println(“##### [” + System.currentTimeMillis() + “] ActivityThread.performLaunchActivity(” + r + “)”);

  3. ActivityInfo aInfo = r.activityInfo;

  4. if (r.packageInfo == null) {

  5. r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,

  6. Context.CONTEXT_INCLUDE_CODE);

  7. }

  8. //首先从intent中解析出目标activity的启动参数

  9. ComponentName component = r.intent.getComponent();

  10. if (component == null) {

  11. component = r.intent.resolveActivity(

  12. mInitialApplication.getPackageManager());

  13. r.intent.setComponent(component);

  14. }

  15. if (r.activityInfo.targetActivity != null) {

  16. component = new ComponentName(r.activityInfo.packageName,

  17. r.activityInfo.targetActivity);

  18. }

  19. Activity activity = null;

  20. try {

  21. java.lang.ClassLoader cl = r.packageInfo.getClassLoader();

  22. //用ClassLoader(类加载器)将目标activity的类通过类名加载进来并调用newInstance来实例化一个对象

  23. //其实就是通过Activity的无参构造方法来new一个对象,对象就是在这里new出来的。

  24. activity = mInstrumentation.newActivity(

  25. cl, component.getClassName(), r.intent);

  26. StrictMode.incrementExpectedActivityCount(activity.getClass());

  27. r.intent.setExtrasClassLoader(cl);

  28. if (r.state != null) {

  29. r.state.setClassLoader(cl);

  30. }

  31. } catch (Exception e) {

  32. if (!mInstrumentation.onException(activity, e)) {

  33. throw new RuntimeException(

  34. "Unable to instantiate activity " + component

  35. + ": " + e.toString(), e);

  36. }

  37. }

  38. try {

  39. Application app = r.packageInfo.makeApplication(false, mInstrumentation);

  40. if (localLOGV) Slog.v(TAG, "Performing launch of " + r);

  41. if (localLOGV) Slog.v(

  42. TAG, r + “: app=” + app

  43. + “, appName=” + app.getPackageName()

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以添加V获取:vip204888 (备注Android)
img

最后是今天给大家分享的一些独家干货:

【Android开发核心知识点笔记】

【Android思维脑图(技能树)】

【Android核心高级技术PDF文档,BAT大厂面试真题解析】

【Android高级架构视频学习资源】

本文已被CODING开源项目:《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》收录

一个人可以走的很快,但一群人才能走的更远。如果你从事以下工作或对以下感兴趣,欢迎戳这里加入程序员的圈子,让我们一起学习成长!

AI人工智能、Android移动开发、AIGC大模型、C C#、Go语言、Java、Linux运维、云计算、MySQL、PMP、网络安全、Python爬虫、UE5、UI设计、Unity3D、Web前端开发、产品经理、车载开发、大数据、鸿蒙、计算机网络、嵌入式物联网、软件测试、数据结构与算法、音视频开发、Flutter、IOS开发、PHP开发、.NET、安卓逆向、云计算

【Android高级架构视频学习资源】*

本文已被CODING开源项目:《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》收录

一个人可以走的很快,但一群人才能走的更远。如果你从事以下工作或对以下感兴趣,欢迎戳这里加入程序员的圈子,让我们一起学习成长!

AI人工智能、Android移动开发、AIGC大模型、C C#、Go语言、Java、Linux运维、云计算、MySQL、PMP、网络安全、Python爬虫、UE5、UI设计、Unity3D、Web前端开发、产品经理、车载开发、大数据、鸿蒙、计算机网络、嵌入式物联网、软件测试、数据结构与算法、音视频开发、Flutter、IOS开发、PHP开发、.NET、安卓逆向、云计算

  • 13
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值