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

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

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

前言

就在上周(2019 年 6 月 12 日),某张在他的公号做了一份区别于某乎的、相对来说有一定参考价值的(Android)薪资状况调查。

投票结果显示,在参与的 27000 人中:

没想到结果刚一公布,就有各种小姐姐后台留言,表示想认识认识那 2% 的 630 人,

嘴上说 —— 别误会,没别的意思,就是单纯的想交个朋友、聊聊人生这样 —— 然而姑娘们的心思,早已让人看穿 🙄

本来这份报告看看也就过去了,没想到,回头猛一想,小姐姐们根据择偶标准发起了请求,这择偶标准不正是 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 的页面跳转路由机制 🙈

其实之前也想过,考虑到 路由机制 被设计为是三大组件(Activity,Service,Broadcast)公用的,要不就将路由机制放在《本地通信大家族》这一章讲。

因为如果现在就讲了,那我怎么帮助大家理解 路由机制 的主人公 Intent 和 Binder 的概念及关系呢(缘于 Binder 并不打算放在《显示系统大家族》中细讲)。

然而又考虑到,如果不先把 Intent 给介绍了,那么下一篇万一是介绍 Fragment,我又拿什么来帮助大家理解 Activity 和 Fragment 二者在路由上的区别和联系呢?🙉

于是,再三考虑下,我决定先把 路由机制、三大组件 的缘起和职责,绝不含糊地过一遍。

并且 Intent 的匹配机制 和 Activity 的路由,作为重点单独拎出来讲。

—— 就当是先介绍个基础,为后续对本地通信的介绍做铺垫。因而,关于本地通信和路由机制,光是看了这篇,你也没白来!😉

为何存在路由的设计?

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

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

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

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

《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 的匹配依据?

top Created with Sketch.