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

前言

就在上周(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 的组件。

top Created with Sketch.