




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、上文介绍了 Android应用程序的启动过程,即应用程序默认 Activity的启动过程,一般来说,这种默认 Activity是在新的进程和任务中启动的;本文将继续分析在应用程序内部启动非默认Activity的过程的源代码,这种非默认Activity 一般是在原来的进程和任务中启动的。这里,我们像上一篇文章Android应用程序启动过程源代码分析一样,采用再上一篇文章Android应用程序的Activity启动过程简要介绍和学习计划所举的例子来分析在应用程序内部启动非默认Activity的过程。在应用程序内部启动非默认Activity的过程与在应用程序启动器Launcher中启动另外一个应用程
2、序的默认Activity的过程大体上一致的,因此,这里不会像上文 Android应用程序启动过程源代码分析一样详 细分析每一个步骤,我们着重关注有差别的地方。回忆一下Android应用程序的Activity启动过程简要介绍和学习计划 一文所用的应用程序 Activity, 它包含两个Activity,分别是MainActivity和SubActivity,前者是应用程序的默认 Activity,后者是非默认 Activity。MainActivity启动起来,通过点击它界面上的按钮,便可以在应用程序内部启动SubActivity。我们先来看一下应用程序的配置文件AndroidManifest.
3、xml ,看看这两个 Activity是如何配置的:view plain1.v?xml version ="1.0"encoding ="utf-8"?>2.<ma ni festxmln s:a ndroid=" ndroid"3.package ="sh yu o.activity"4.an droid:vers ion Code="1"5.android:versionName="1.0" >6.<applicati onan droid:ic
4、on="drawable/ico n"an droid:label= "stri ng/app_ name">7.<activityan droid:n ame='.Mai nActivity"8.an droid:label= "stri ng/app_ name">9.vinten t-filter>10.<act ionan droid:n ame ="a ndroid.i nten t.acti on. MAIN"/>11.vcategoryan dro
5、id:n ame ="a ndroid.i nten t.category.LAUNCHER"/>12.</inten t-filter>13.v/activity>14.vactivityan droid:n ame='.SubActivity"15.an droid:label= "stri ng/sub_activity">16.vinten t-filter>17.vact ionan droid:n ame="shyu o.activity.subactivity"/&g
6、t;18.vcategoryan droid:n ame="a ndroid.i nten t.category.DEFAULT"/>19.</inten t-filter>20.v/activity>21.v/applicati on>22.</ma nifest>这里可以很清楚地看到,MainActivity被配置成了应用程序的默认 Activity,而SubActivity可以通过名称 “shy.luo.activity.subactivity 隐式地启动,我们来看一下 src/shy/luo/activity/MainAct
7、ivity.java文件的内容,可以清楚地看到 SubActivity是如何隐式地启动的:view plain1. public class Main Activityexte nds Activityimpleme nts On ClickListe ner 2. 3.3. Override4. public void on Click(View v) 5. if (v.equals(startButton) 6. Intent intent =new lntent("sh yu o.activity.subactivity");7. startActivity(i nt
8、e nt);8. 9. 10. 这里,首先创建一个名称为“shy.luo.activity.subactivity的Intent",然后以这个Intent为参数,通过调用startActivity 函数来实现隐式地启动SubActivity。有了这些背景知识后,我们就来看一下SubActivity启动过程的序列图:«円frl m 円点击查看大图与前面介绍的MainActivity启动过程相比,这里少了中间创建新的进程的步骤;接下来,我们就详细分析一下SubActivity与MainActivity启动过程中有差别的地方,相同的地方请参考 Android应用程序启动 过程源代
9、码分析一文。Step 1. Activity.startActivity这一步与上一篇文章 Android应用程序启动过程源代码分析的Step 2大体一致,通过指定名称“ shy.luo.activity.subactivity来告诉应用程序框架层,它要隐式地启动SubActivity。所不同的是传入的参数intent 没有 lntent.FLAG_ACTIVITY_NEW_TASK标志,表示这个 SubActivity 和启动它的 MainActivity 运行在同一个Task中。Step 2. Activity.startActivityForResult这一步与上一篇文章Android应
10、用程序启动过程源代码分析Step 3. Instrumentation.execStartActivity这一步与上一篇文章Android应用程序启动过程源代码分析的 Step 3 一致。的 Step 4 一致。Step 4. ActivityManagerProxy.startActivity这一步与上一篇文章 Android应用程序启动过程源代码分析的Step 5 一致。Step 5. ActivityManagerService.startActivity这一步与上一篇文章 Android应用程序启动过程源代码分析的 Step 6 一致。Step 6. ActivityStack.sta
11、rtActivityMayWait这一步与上一篇文章 Android应用程序启动过程源代码分析的Step 7 一致。Step 7. ActivityStack.startActivityLocked这一步与上一篇文章 Android应用程序启动过程源代码分析的Step 8 一致。Step 8. ActivityStack.startActivityUncheckedLocked |这一步与上一篇文章Android应用程序启动过程源代码分析的Step 9有所不同,主要是当前要启动的Activity与启动它的Activity是在同一个Task中运行的,我们来详细看一下。这个函数定义在framewo
12、rks/base/services/java/com/android/server/am/ActivityStack.java文件中:view plain.5.6.public class ActivityStack final int startActivityU ncheckedLocked(ActivityRecord r,ActivityRecord sourceRecord, Uri gran tedUriPermissi grantedMode,boolean onlylfNeeded,boolea n doResume) 1.12
13、.9.50.final Intent intent = r.i ntent;final int calli ngUid = raun chedFromUid;int laun chFlags = inten t.getFlags();if (sourceRecord = null ) else if (sourceRecord.launchMode = ActivityInfo.
14、LAUNCH_SINGLE_INSTANCE) else if (r.launchMode = ActivityInfo.LAUNCH_SINGLE_INSTANCE0) if (r.resultTo !=null && (launchFlags&lntent.FLAG_ACTIVITY_NEW_TASK) !=boolea n addi ngToTask =falseif (launchFlags&lntent.FLAG_ACTIVITY_NEW_TASK) !=0 &&(lau nchFlags&lnten t.FLAG_ACTIVI
15、TY_MULTIPLE_TASK) =0)| r.lau nchMode = Activit yin fo.LAUNCH_SINGLE_TASK| r.lau nchMode = ActivityI nfo.LAUNCH_SINGLE_INSTANCE) if (r.packageName != null ) / If the activity being laun ched is the same as the one curre ntly / at the top, then we need to check if it should only be launched / on ce.Ac
16、tivityRecord top = topR unningNon DelayedActivityLocked( no tTop);if (top != null && r.resultTo =null ) if (top.realActivity.equals(r.realActivity) else boolea n n ewTask = false0.61./ Should this be con sidered a new task?if (r.resultTo =null && !addingTo
17、Task&& (lau nchFlags&lnten t.FLAG_ACTIVITY_NEW_TASK) !=0) else if (sourceRecord !=null ) / An existing activity is starting this new activity, so we want/ to keep the new one in the same task as the one that is start ing/ it.8.r.task = sourceRecord.task;else
18、5.没有设置,在配置文件于是它就默认标准模式,即startActivityLocked(r, n ewTask, doResume);return START_SUCCESS;76.77. 这里,参数 intent 的标志位 lntent.FLAG_ACTIVITY_NEW_TASK AndriodManifest.xml 中,SubActivity 也没有配置启动模式 launchMode , Activitylnfo.LAUNCH_MULTIPLE,因此,下面 if 语句不会执行:view plain1. if (launchFlags&lntent.FLAG_A
19、CTIVITY_NEW_TASK) !=0 &&2. (lau nchFlags&ln te nt.FLAG_ACTIVITY_MULTIPLE_TASK) =0)3. | r.lau nchMode = Activityl nfo.LAUNCH_SINGLE_TASK4. | r.lau nchMode = Activityl nfo.LAUNCH_SINGLE_INSTANCE) 5于是,变量 addingToTask 为 false继续往下看:1. if (r.packageName !=null ) 2. /If the activity being laun
20、ched is the same as the one curre ntly3. / at the top, then we need to check if it should only be launched4. / on ce.5. ActivityRecord top = topR unningNon DelayedActivityLocked( no tTop);6. if (top != null && r.resultTo =null ) 7. if (top.realActivity.equals(r.realActivity) 8. 9. 10. 11.12.
21、 这里看一下当前要启动的 Activity是否就是当前堆栈顶端的Activity,如果是的话,在某些情况下,就不用再重新启动了。函数topRunningNonDelayedActivityLocked 返回当前堆栈顶端的Activity,这里即为 MainActivity,而当前要启动的 Activity为SubActivity,因此,这二者不相 等,于是跳过里面的if语句。接着往下执行:view plain1. / Should this be con sidered a new task?2. if (r.resultTo =null && !addingToTask3.
22、&& (lau nchFlags&ln te nt.FLAG_ACTIVITY_NEW_TASK) !=0) 45.5. else if (sourceRecord !=null ) 78. / An existi ng activity is start ing this new activity, so we want9. / to keep the new one in the same task as the one that is start ing10. / it.11. r.task = sourceRecord.task;1213.14. else 15
23、16.前面说过参数intent的标志位lntent.FLAG_ACTIVITY_NEW_TASK没有设置,而这里的sourceRecord 即为当前执行启动Activity操作的Activity,这里即为 MainActivity,因此,它不为 null,于是于MainActivity所属的Task设置到r.task中去,这里的r即为SubActivity。看到这里,我们就知道 SubActivity 要和 MainActivity 运行在同一个 Task中了,同时,变量 newTask的值为false。最后,函数进 入startActivityLocked(r, newTask, doRes
24、ume)进一步处理了。这个函数同样是定义在 frameworks/base/services/java/com/android/server/am/ActivityStack.java文件中:view plain..9.publicclass ActivityStack private final void startActivityLocked(ActivityRecord r, boo
25、lea n doResume) final int NH = mHistory.size();boolea n n ewTask,int addPos = -1;if (!newTask) / If starting in an existing task, find where that is.boolean startIt = true ;for (int i = NH- 1; i >=0; i-) ActivityRecord p = (ActivityRecord)mHistory.get(i);if (p.finishing) con ti nue ;if (p.task =
26、r.task) / Here it is! Now, if this is n ot yet visible to the/ user, the n just add it without start in g; it will/ get started whe n the user n avigates back to it.addPos = i+1 ;if (!startIt) mHistory.add(addPos, r);r.inHistory =true ;r.task .n umActivities+;mService.mWi ndowMa nager.addAppToke n(
27、addPos, r, r.task.taskId,r.i nfo.scree nOrie ntati on, r.fullscree n);if (VALIDATE_TOKENS) mService.mWi ndowMa nager.validateAppToke ns(mHistory);return ;break ;if (p.fullscreen) startIt =false ;4.45./ Slot the activity into the history stack and proceed46.mHistory.add(addPos, r);47.r.inHi
28、story =true ;48.r.fron tOITask = n ewTask;49.r.task .n umActivities+;3.if (doResume) 54.resumeTopActivityLocked(null );8.59.60.这里传进来的参数 newTask为false , doResume 为true。当newTask为false,表示即将要启动 的Activity是在原有的Task运行时,如果这个原有的Task当前对用户不可见时,这时候就不需要继续执行下去了,因为即使把这个 Activity启动起来,用户也看不到,还不如先
29、把它保存起来,等到下次这个Task 对用户可见的时候,再启动不迟。这里,这个原有的 Task,即运行MainActivity的Task当前对用户是可 见的,因此,会继续往下执行。接下去执行就会把这个SubActivity通过mHistroy.add(addPos, r)添加到堆栈顶端去,然后调用resumeTopActivityLocked进一步操作。Step 9. ActivityStack.resumeTopActivityLocked这一步与上一篇文章 Android应用程序启动过程源代码分析的Step 10 一致。但是要注意的是,执行到这个函数的时候,当前处于堆栈顶端的Activity
30、为SubActivity , ActivityStack的成员变量 mResumedActivity 指向 MainActivity 。Step 10. ActivityStack.startPausingLocked这一步与上一篇文章 Android应用程序启动过程源代码分析的Step 11 一致。从这里开始,ActivityManagerService 通知 MainActivity 进入 Paused 状态。Step 11. ApplicationThreadProxy.schedulePauseActivity这一步与上一篇文章 Android应用程序启动过程源代码分析的Step 12
31、 一致。Step 12. ApplicationThread.schedulePauseActivity这一步与上一篇文章Android应用程序启动过程源代码分析的 Step 13 一致。Step 13. ActivityThread.queueOrSendMessage这一步与上一篇文章 Android应用程序启动过程源代码分析的 Step 14 一致。Step 14. H.handleMessage这一步与上一篇文章Android应用程序启动过程源代码分析的 Step 15 一致。Step 15. ActivityThread.handlePauseActivity这一步与上一篇文章And
32、roid应用程序启动过程源代码分析的 Step 16一致。Step 16. ActivityManagerProxy.activityPaused这一步与上一篇文章Android应用程序启动过程源代码分析的 Step 17一致。2.2.Step 17. ActivityManagerService.activityPaused这一步与上一篇文章Android应用程序启动过程源代码分析的 Step 18一致。2.2.Step 18. ActivityStack.activityPaused这一步与上一篇文章Android应用程序启动过程源代码分析的 Step 19一致。Step 19. Acti
33、vitySpletePauseLocked这一步与上一篇文章Android应用程序启动过程源代码分析的 Step 20 一致。执行到这里的时候,MainActivity就进入Paused状态了,下面就开始要启动SubActivity 了。Step 20. ActivityStack.resumeTopActivityLokced这一步与上一篇文章Android应用程序启动过程源代码分析的 Step 21 一致。Step 21. ActivityStack.startSpecificActivityLocked会调用mService.startProcessLocked来创建一个新的进程来启动新
34、的Activity,我们来看一下这个函数的实现,这个函数定义在view plainframeworks/base/services/java/com/android/server/am/ActivityStack.java文件中:这一步与上一篇文章Android应用程序启动过程源代码分析的Step 22就有所不同了,这里,它不1. public class ActivityStack .private final void startSpecificActivityLocked(ActivityRecord r,6.boolea n an dResume,boolea n che
35、ckC on fig) 7./ Is this activity's application already running?8.ProcessRecord app = mService.getProcessRecordLocked(cessName,9.r.i nfo.applicati onln fo.uid);3.if (app !=null&& app.thread !=null ) 14.try 15.realStartActivityLocked(r, app, an dResume, checkC on fig);16.ret
36、urn ;17.catch (RemoteExcepti on e) 7.28.这里由于不是第一次启动应用程序的Activity ( MainActivity是这个应用程序第一个启动的Activity ),所以下面语句:view plain1. ProcessRecord app = mService.getProcessRecordLocked(cessName,2. n fo.applicati onln fo.uid);取回来的app不为null。在上一篇文章 Android应用程序启动过程源代码分析中,我们介绍过,在Ac
37、tivity应用程序中的 AndroidManifest.xml 配置文件中,我们没有指定 application 标签的process属性, 于是系统就会默认使用 package的名称,这里就是"shy.luo.activity" 了。每一个应用程序都有自己的 uid, 因此,这里uid + process 的组合就可以创建一个全局唯一的ProcessRecord。这个 ProcessRecord 是在前面启动MainActivity时创建的,因此,这里将它取回来,并保存在变量app中。注意,我们也可以在AndroidManifest.xml 配置文件中指定 SubAct
38、ivity 的process属性值,这样 SubActivity 就可以在另外一个 进程中启动,不过很少有应用程序会这样做,我们不考虑这种情况。这个app的thread也是在前面启动 MainActivity时创建好的,于是,这里就直接调用 realStartActivityLocked函数来启动新的 Activity 了,新的Activity的相关信息都保存在参数r中了。Step 22. ActivityStack.realStartActivityLocked这一步与上一篇文章 Android应用程序启动过程源代码分析的Step 28 一致。Step 23. ApplicationThre
39、adProxy.scheduleLaunchActivity这一步与上一篇文章Android应用程序启动过程源代码分析的 Step 29 一致。Step 24. ApplicationThread.scheduleLaunchActivity这一步与上一篇文章Android应用程序启动过程源代码分析的 Step 30 一致。Step 25. ActivityThread.queueOrSendMessage这一步与上一篇文章Android应用程序启动过程源代码分析的 Step 31 一致。Step 26. H.handleMessage这一步与上一篇文章Android应用程序启动过程源代码分析
40、的 Step 32 一致。Step 27. ActivityThread.handleLaunchActivity这一步与上一篇文章 Android应用程序启动过程源代码分析Step 28. ActivityThread.performLaunchActivity这一步与上一篇文章 Android应用程序启动过程源代码分析ClassLoader 里面加载的类就是 shy.luo.activity.SubActivity 了。的 Step 33 一致。的Step 34 一致,不过,这里要从Step 29. SubAcitiviy.onCreate这个函数定义在 packages/experimental/Activity/src/shy/luo/activity/SubActivity.java文件中,这是我们自定义的app工程文件:view plain1. public class SubActivityexte nds Activit
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 上海现代化工职业学院《大学生职业生涯与发展规划》2023-2024学年第二学期期末试卷
- 桂林旅游学院《普通话与教师口语》2023-2024学年第二学期期末试卷
- 长春医学高等专科学校《信息检索竞赛》2023-2024学年第一学期期末试卷
- 四川省内江市2025年五下数学期末经典试题含答案
- 河南省郑州市金水区评价2025年三年级数学第二学期期末监测模拟试题含解析
- 重庆医药高等专科学校《听力障碍儿童心理与教育》2023-2024学年第二学期期末试卷
- 贵州毕节市威宁县第八中学2024-2025学年高三下-等级考调研(二模)语文试题试卷含解析
- 电子科技大学成都学院《影视非线性编辑》2023-2024学年第二学期期末试卷
- 湖南长沙市岳麓区重点达标名校2025届初三第三次模拟考试试题化学试题含解析
- 汝州市2024-2025学年五下数学期末质量检测模拟试题含答案
- 北京小客车指标车牌租赁协议模板
- 2025年浙江省杭州市余杭区中考语文模拟试卷含答案
- 摊铺机租赁合同协议书范本
- 儿童画教材课件
- 用户画像的构建与应用试题及答案
- 2025道德讲堂课件
- 广东省2025年普通高等学校招生全国统一考试模拟测试(一)英语试题及答案
- 学生心理健康一生一策档案表
- 2025年湖南省长沙市初中学业水平考试模拟(一)历史试题(原卷版+解析版)
- 2025年上半年绵竹市九绵产业投资限公司招聘易考易错模拟试题(共500题)试卷后附参考答案
- 国家义务教育质量监测八年级美术样卷
评论
0/150
提交评论