Android之ICC机制(一)
前言
组件间通信(Inter-Component Communication, ICC)是Android特有的机制之一。以系列文章记录一下对ICC的认识。本文讲解第一部分“ICC是什么”。
一、ICC是什么
定义
Android应用是基于组件来实现功能,经典四大组件包括Activity, Service, BroadcastReceiver, Content Provider。Android从系统层面实现了ICC,让这些组件之间可以进行信息传递,一个组件可以调用一个或多个Android API,向另一个或多个组件传递信息,(然后接收反馈信息)。
分类
对于学习中所见过的ICC,将其分为Intent消息传递,非典型ICC,路由框架三类。
Intent 消息传递
Intent实现组件间通信有两种形式:显式Intent (Explicit intent) 和 隐式Intent (Implicit intent)
显式Intent:直接指定需要跳转的组件
1
2Intent intent = new Intent(this,testActivity.class)
startActivity(intent)隐式Intent:不明确指定启动的组件,而是指定Action、Category、Data属性。每个组件在Manifest.xml文件中注册时用< intent-filter>字段来描述这几个属性,隐式Intent实现的ICC将由Android系统根据Mainfest.xml筛选出符合属性的组件。
如Manifest.xml文件中注册两个Activity如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17# DroidBench--ActivityCommunication4.apk
<activity android:label="@string/app_name" android:name="edu.mit.icc_concat_action_string.OutFlowActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity android:label="@string/app_name" android:name="edu.mit.icc_concat_action_string.InFlowActivity">
<intent-filter>
<action android:name="edu.mit.icc_concat_action_string.ACTION"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>使用隐式Intent完成ICC
1
2Intent i = new Intent("edu.mit.icc_concat_action_string.ACTION");
this.startActivity(i);系统将从当前组件跳转到 edu.mit.icc_concat_action_string.InFlowActivity
非典型ICC
“Atypical ICC” (我译为“非典型ICC”)这一概念是从文章RAICC: Revealing Atypical Inter-Component Communication in Android Apps(ICSE 2021)中看到的,即有些方法的原始目的不是用于ICC,但是可以用于实现ICC。通常这些方法会依赖PendingIntents 和 IntentSenders。
以论文中的例子说明:下图中,行4显式指定了AlarmListener的intent,行6PendingIntent封装这个intent,行8通过AlarmManager.set()执行pendingIntent。这里的AlarmManager.set方法就是一个非典型ICC。
路由框架
在模块化开发的场景下,直接使用Intent会使模块间耦合严重。为了降低耦合度,一个直观思路是写配置文件来管理所有的组件信息,将这个思路实现得更高级完善,也就是所谓的路由框架(粗浅理解)。常见路由框架如阿里自研的ARouter,就用于解决模块间的界面跳转问题。
路由框架通过注释方式在目标组件添加路由,并维护路由表对路由进行统一管理。举个例子:
target activity:
1 | @RouterTarget(path = "/test/faceauthentry") |
source activity跳转到target Activity:
1 | ARouter.getInstance().build("/test/faceauthentry").navigation(); |
小结
本篇文章记录了个人对ICC的理解,以及对所见过的ICC类型进行总结,主要包括Intent消息传递,非典型ICC,路由框架三类ICC。其中Intent是最常见的组件间通信方式;非典型ICC指那些依赖PendingIntents 和 IntentSenders,可以用于实现ICC的API;路由框架则是现在一种比较流行的界面跳转机制,可以实现模块之间解耦合。