《Android编程权威指南》之深入学习intent和任务(二)

245 阅读4分钟

「这是我参与11月更文挑战的第20天,活动详情查看:2021最后一次更文挑战

《Android编程权威指南》第 23 章第二篇,周末了,偷偷懒,哈哈哈~

四、任务与回退栈

Android 使用任务来跟踪应用运行的状态。

任务是一个 activity 栈。栈底部的 activity 通常称为基 activity。栈顶的 activity 用户能看得到。按回退键,栈顶 activity 会弹出栈外。如果用户看到的是基 activity,按回退键,系统就会回到主屏幕。

有关 Activity 任务栈,可以看看扔物线的视频,讲的很详细易懂,一看就懂,不过还是需要多看几遍,思考一下,最好再实践一下理解更深刻:

www.bilibili.com/video/BV1CA…

当前应用去打开其他的 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都处在独立的任务中。

多个 Google Drive 任务

如果需要应用启动多个任务,可给 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)

运行效果「丑丑的」:

result

其他

NerdLauncher 项目 Demo 地址:

github.com/visiongem/A…


🌈关注我吖~❤️

公众号:妮K妮K妮