「这是我参与11月更文挑战的第20天,活动详情查看:2021最后一次更文挑战」
《Android编程权威指南》第 23 章第二篇,周末了,偷偷懒,哈哈哈~
四、任务与回退栈
Android 使用任务来跟踪应用运行的状态。
任务是一个 activity 栈。栈底部的 activity 通常称为基 activity。栈顶的 activity 用户能看得到。按回退键,栈顶 activity 会弹出栈外。如果用户看到的是基 activity,按回退键,系统就会回到主屏幕。
有关 Activity 任务栈,可以看看扔物线的视频,讲的很详细易懂,一看就懂,不过还是需要多看几遍,思考一下,最好再实践一下理解更深刻:
当前应用去打开其他的 App,其他 App 的启动 Activity 都是运行在自身的任务栈中的,为了在启动新 activity 时启动新任务,需要为 intent 添加一个标志:
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
FLAG_ACTIVITY_NEW_TASK 标志控制每个 activity 仅创建一个任务。如果那个被打开的 activity 没有任务栈就会创建一个新的任务栈,如果已经有了一个运行的任务,Android 就会自动切回到那个任务,就不再创建新的任务了。
五、用 NerdLauncher 当主屏幕
这里实践把 NerdLauncer 应用成 Android 主界面(home screen),「我们的桌面实际上也是 Android 系统中的一个应用,显示着我们安装的各个 App,给我们启动 App 的入口」。
只需要修改 NerdLauncherActivity 的类别即可,打开 manifests/AndroidManifest.xml:
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<category android:name="android.intent.category.HOME" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
不过我这里实践按主屏幕键没有看到书中的那个框,可能跟 Android 版本有关。下次再研究一下。
六、深入学习:进程与任务
『进程』 是操作系统创建的、供应用对象生存以及应用运行的地方。通常会拥有由操作系统管理着的一些系统资源,比如内存、网络端口以及打开的文件等。拥有至少一个执行线程,Android 系统中,每个进程都需要一个 虚拟机 来运行。
Android 4.4(KitKat)之前,Dalvik 是 Android 操作系统使用的进程虚拟机。进程只要一启动,就会有一个 Dalvik 虚拟机新实例跳出来收留它。不过,自Android 5.0(Lollipop)开始,Android运行时(ART)取代了 Dalvik,已成为公认的进程虚拟机。
之前的应用 CriminalIntent,联系人应用虽然是 CriminalIntent 打开的,联系人列表 activity 会被加入到 CriminalIntent 应用任务中,可是联系人 activity 实例实际是在联系人应用进程的内存空间创建的,而且也是在该应用进程里的虚拟机上运行的。如图所示:
接下来再去试验一个过程,在 CriminalIntent 中进入联系人列表,按 Home 回到桌面,从桌面去启动联系人应用,从联系人列表中选取联系人或添加联系人。这个过程,系统会在联系人应用进程中创建新的联系人列表 activity 和联系人明细界面实例。也会创建联系人应用新任务。这个新任务会引用联系人列表和联系人明细界面 activity 实例,如图所示:
理解完本章,我们应该知道,Google Play 商店中一些自称为任务终止器的应用,实际上都是进程终止器。这些应用会“杀掉”某个进程,这表明,它们可能正在销毁其他应用任务引用的 activity。
七、深入学习:并发文档
并发文档(concurrent document):在Android Lollipop(API 级别 21)上引入,可以为运行的应用动态创建任意数目的任务。
Google Drive 是并发文档概念应用的最好实例。用户可以用它打开并编辑多份文档。从概览屏可以看到,这些文档编辑activity都处在独立的任务中。
如果需要应用启动多个任务,可给 intent 打上 Intent.FLAG_ACTIVITY_NEW_DOCUMENT 标签,再调用startActivity(...)函数;或在 manifest 中,为 activity 设置如下 documentLaunchMode:
android:documentLaunchMode="intoExisting"
这样,一份文档只会对应一个任务。(如果发送带有和已存在任务相同数据的intent,系统就不会再创建新任务。)如果无论如何都想创建新任务,那就给intent 同时打上 Intent.FLAG_ACTIVITY_NEW_DOCUMENT 和 Intent.FLAG_ACTIVITY_MULTIPLE_TASK 标签,或把 manifest 中的 documentLaunchMode 属性值改为 always。
自行实践~ O(∩_∩)O哈哈~
八、挑战练习:应用图标
给 NerdLauncher 应用中显示的所有应用添加图标。
简单的呢,就是在给列表设置文字内容的下面添加代码:
val appIcon = resolveInfo.loadIcon(packageManager)
appIcon.setBounds(0, 0, appIcon.minimumWidth, appIcon.minimumHeight)
tvName.setCompoundDrawables(appIcon, null, null, null)
运行效果「丑丑的」:
其他
NerdLauncher 项目 Demo 地址:
🌈关注我吖~❤️
公众号:妮K妮K妮