美文网首页Android技术知识Android开发经验谈Android开发
Android 开发艺术探索学习笔记(一)

Android 开发艺术探索学习笔记(一)

作者: aJIEw | 来源:发表于2019-12-08 21:14 被阅读0次
    Go, Android, go!

    结合 官方文档 阅读《Android 开发艺术探索》时所做的学习笔记。本篇记录第一章。

    Activity 生命周期

    • 新 Activity 启动之前,原栈顶 Activity 的 onPause 会先被调用,所以不要在 onPause 中做耗时操作。
    • onRestoreInstanceState 方法会在 onStart 之后被调用,推荐在这里而不是 onCreate 方法中恢复数据。大部分 View 都会帮我们做一些基本的状态恢复,但是必须为 View 提供 ID,可以查看对应的 View 中的 onRestoreInstanceState 方法了解具体恢复了哪些内容。
    • onSaveInstanceState方法会在 onStop 之前被调用, 用于保存一些轻量的数据,它可以作为生命周期方法的补充,有些时候并不会被调用,比如从 B 返回 A 中的时候。

    Activity 的启动模式

    四种启动模式

    • standard:每次都会在当前任务栈中启动一个新的 Activity 实例。
    • singleTop:栈顶复用,再次启动时会调用 onNewIntent() 而不是 onCreate()。
    • singleTask:栈内复用,一般与 taskAffinity 结合使用,与 singleTop 类似,如果在请求的目标栈中已有实例存在,则会调用 onNewIntent()。另外,singleTask 启动模式还有 CLEAR_TOP 的效果,比如 A、B 两个 activity 位于同一个任务栈,如果 A 是 singleTask,而且被另一个任务栈的 activity 再次启动,则 B 会出栈。
    • singleInstance:加强的 singleTask,只能单独位于一个任务栈中。

    关于 taskAffinity

    • 指定 Activity 在哪个栈中运行,默认使用 applicationId。
    • 具有相同 taskAffinity 的 activity 会被放入同一个栈中。
    • 一般需要配合 singleTask 启动模式来使用。

    关于 allowTaskReparenting

    • 当启动该 activity 的时候,如果该 activity 存在相同的 taskAffinity 的栈,则会被移动到那个栈里。比如一个浏览器应用 App A 中的 activity A 指定了 allowTaskReparenting,同时与主 activity 位于同一个任务栈中。那么当你在别的应用 App B 中,点击了一个链接打开了 A,然后再返回桌面打开浏览器应用,会直接打开 activity A 而不是主 activity,而当我们返回 App B 的时候,会发现这个 activity A 已经不在了(被移动到了 App A 的任务栈中)。
    • 我们一般结合 singleTask 并指定单独的栈来使用 allowTaskReparenting。

    关于 Intent Flags

    singleTask 和 singleInstance 的区别

    • singleTask 启动模式下,当栈和 activity 都不存在的时候,系统会创建一个新的 activity 放入新的栈内,如果栈存在则直接将 activity 入栈,而且除了相同 taskAffinity 的 activity 之外,还允许其他 activity (i.e. standard 和 singleTop 的 activity) 入栈。

    • singleInstance 启动模式下的 activity 不允许其他 activity 入栈,也就是说栈内永远只有这一个 activity。

    IntentFilter 的匹配规则

    关于 IntentFilter 的组成

    • 一组 IntentFilter 可以由多个 action category data 组成,必须同时匹配 action category data 才能成功启动对应的组件。
    • 如果该组件只能处理特定某几种的 action category data 组合,那么你就必须创建多个对应的 IntentFilter 而不是把他们全都放一起。

    关于 通过匹配测试

    • action:指定接收动作类型,用 android:name 指定,可以有 0 个或者多个。一个 Intent 想要匹配成功,则必须至少匹配上一个 action,intent-filter 中可以指定比 Intent 中更多的 action。另外,
      • 如果 intent-filter 没有指定 action,则所有 Intent 都无法匹配成功;
      • 如果 Intent 没有指定 action,那么这个 Intent 会通过所有指定了 action 的 intent-filter。
    • cateogry:指定接收分类。如果 Intent 中指定了多个 category,那么必须全都匹配上才能匹配成功。其他与 action 相同。
      • 使用隐式 Intent 的时候,系统默认添加上一个 CATEGORY_DEFAULT,所以如果你想要匹配成功就必须添加 android.intent.category.DEFAULT
    • data:指定 URI 和 MIME type
      • URI 包括以下属性:scheme, host, port, path,host 有时也称为 authority。
        • 完整格式:<scheme>://<host>:<port>/<path>
        • 例子:content://com.example.project:200/folder/subfolder/etc
        • 每个属性都是可选的,但是有先后依赖关系,比如如果没有指定 scheme,那么即使指定了 host 或者 port 或者 path 也是无效的。
        • URI 支持部分匹配。
      • 完整 MIME type 列表可参考 IANA MIME Media Types,不同机型支持的 MIME type 有所不同。
      • URI 和 MIME type 匹配有如下规则:
        • 完全匹配,比如如果 Intent 只指定了 MIME type,那么所有只指定了 MIME type 都会通过匹配。
        • 如果 intent-filter 指定了 MIME type,那么默认支持 content: or file: URI,即如果 Intent 指定了该 MIME type 同时又指定了 scheme 为 content 或者 file 则可以匹配成功。
      • 如果要为 Intent 设置完整的 data 和 type,必须调用 setDataAndType,因为 setData 和 setType 会相互消除。

    关于 Intent 匹配

    • 我们可以使用 PackageManagerresove... 以及 query... 方法,来确定是否存在可以调用的组件,前者会返回匹配到的最佳组件,后者返回所有匹配到的组件。
    • 记得使用 MATCH_DEFAULT_ONLY flag 来过滤掉没有声明 android.intent.category.DEFAULT 的组件。

    相关文章

      网友评论

        本文标题:Android 开发艺术探索学习笔记(一)

        本文链接:https://www.haomeiwen.com/subject/htkvgctx.html