2fd888d37951d5167ab79c4a74a0650a
重学安卓:Intent 就是你的择偶标准啊!

温馨提示:如果这是第一次接触《重学安卓》,可借助 这份在 GitBook 上维护的 “导读” 来快速了解《重学安卓》专栏、获取它的目录、试读内容,以及了解它的最新动态 和 发展状况。

截至目前,专栏已对 体系化文章 做了 1070 余次修订,数十位群友告诉我 受专栏的启发 他们也开启了写作之路。群里不定期会有小伙伴讨论适配问题、分享原创的开源库 和 提供内推机会,订阅后可随时进群交流。

前言

周末去了趟前同事家叙旧,晚饭时分,在同事的电脑上播放起了相亲节目。台上男嘉宾就自己的事业和收入做了相应的介绍,正对面的女嘉宾们则是根据各自的价值偏好 为心仪的男嘉宾亮起了灯。

本来这相亲节目看看也就过去了,没想到,回头猛一想,小姐姐们根据择偶标准发起了请求,这择偶标准不正是 Intent 的本质么?

于是回到家我吭哧吭哧地写下了这篇《择偶标准指南》,并且开源了 3 个配套的案例,方便大家深入理解和实操(不要慌,文末链接给出)。

所以如果通过这篇,你对 Intent 的设计依据、职责边界,以及和其他路由成员的关系 建立起感性的认识,那我的目的也就达到了。

文章目录一览

  • 前言
  • 不得不先讲的 Intent 匹配机制
  • 关于 Intent 的 7 个深度思考
    • 为何存在路由的设计?
    • 为何存在三大组件的设计?
    • 为何要让 Binder 来当媒婆?
    • Intent 存在哪几种类型?为何存在这样的区别?
    • 隐式 Intent 的匹配依据?
    • IntentFilter 的概念和作用为何?
    • 基于 Intent 和 IntentFilter 的匹配规则,提炼出的 4 个要点
  • 关于 Intent 的 3 个实用方法
  • Intent 使用的 7 个注意事项?
  • 综上

不得不先讲的 Intent 匹配机制

前几期,我们借由

《Activity 生命周期的 3 个辟谣》

《绝不丢失状态的 Activity 重建机制》

《你丢了 offer,只因拎不清 Activity 任务和返回栈》

这 3 篇文章,分别深入浅出地介绍了 进程模式生命周期重建机制状态管理 的设计依据、职责边界,以及相互间关系,并且正确区分了 任务返回栈,乃至正确理解了 启动模式 的本质。

原以为这样 Activity 的知识复盘 便圆满告一段落,没想到掐指一算,还差一篇 —— Activity 的页面跳转路由机制 🙈

并且由于下一篇打算介绍 Fragment,且其中涉及对 “Activity 和 Fragment 在路由上的区别和联系” 的解析,

因而本篇决定先就 “路由”、“组件” 以及 “Intent 匹配机制” 的设计缘由 做个全面的铺垫。就算对择偶不感兴趣,也请务必认真阅读本篇 😉

为何存在路由的设计?

路由的本质即寻址和数据转发。路由的概念源于计算机网络。

正因为这是一种 普适的、标准化的、用于解决页面跳转和通信的 解决方案,因而安卓也是沿用了路由机制,来完成页面的跳转和通信。

下文我们都用“路由”来指代“页面跳转和通信”。

为何存在三大组件的设计?

《Activity 的快乐你不懂!》 一文中,我们已经分析了 Activity 存在的缘由:

是基于模版方法模式的、将页面跳转和生命周期管理 交给系统在背后运筹帷幄、开发者只需拿到继承的简易干净的模板 去填充自己的代码

因而就像 Activity 是对 Window 的模板化,Service、Broadcast 这 2 个组件,本质上也是待继承和填充的模板,是为了方便开发者的使用而存在。

也因此,它们背后拥有同一套“进程间通信”的路由机制,来帮助它们完成相互间的路由。

在这套机制中,Binder 是通风报信的媒婆,Intent 则是择偶标准

为何要让 Binder 来当媒婆?

我们知道,Binder 是 Android 下进程间通信的方式,

那为什么路由的事,要设计成是交给 Binder 去做呢?

—— 因为考虑到有进程间通信的需要 —— 因为 Android 系统被设计为,你不仅可以和当前 App 中的组件通信,你也可以去调用其他 App 的组件,而这时候就需要 Binder 来完成进程间通信。

那为什么要设计成可以调用其他 App 的组件呢?

—— 就比如开发一个日记软件,为了添加照片,难道非要自己写一个相册模块吗?未必,通过路由机制,你就能调用系统相册,来选取和回调所需的照片。

在这个过程中,Binder 通风报信,Intent 则是你选取照片的标准,例如你只要 PNG 格式的照片。

Intent 存在哪几种类型?为何存在这样的区别?

这主要看“人”。

世界上只存在两种人:一种是目标明确、知道自己想要什么的;另一种是目标不明确的、只能给出个大概的条件。

那么前一种人,她给出的择偶标准,就是显式 Intent,具体的表现就是,她会事先明确地指出“我要翻某人的牌”。

也即,通过setComponent()setClass()setClassName()Intent 构造函数,来 明确地指定要启动的组件的名称或类,就是显式 Intent。例如:

后一种人,她给出的是一系列指标,凡是处于这些指标的基准区间的,都可以考虑。

也即,隐式 Intent 的特点是,不事先明确地指出所要启动的组件,而是通过给出条件项,来匹配潜在的、符合条件的组件,从而在对应的组件列表中,供使用者挑选心仪的那一个。例如:

这里特别要提到的一点是,网上对 显式、隐式 Intent 区别的 讹传 屡见不鲜。

首先他们并没有正确地区分 显式和隐式 的概念,认为 “只有往 Intent 传入 class 的那种写法才是显式”,并且认为只有 “隐式” Intent 可以去访问别的 App 的组件。

这样的说法显然是没有事实根据的。

显式和隐式的本质区别,正如本小节中提到的。

并且,不管是显式 Intent 还是 隐式 Intent,只要被访问的外部 App 的目标组件在 menifest 中为该组件配置的 exported 属性为 true,那么就可以访问。

划重点 👆👆👆

因而退一万步,在对一个知识点存疑的情况下,就算等不及《重学安卓》系列文章,也请务必首先查阅官方文档!

https://developer.android.google.cn/guide/components/intents-filters

那么用于匹配的指标都有哪些呢?

隐式 Intent 的匹配依据?

拿去和谁匹配呢?匹配的规则是什么呢?

IntentFilter 的概念和作用为何?

top Created with Sketch.