前言

组件间通信(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
    2
    Intent 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
    2
    Intent 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。

image-20220224203014598

路由框架

在模块化开发的场景下,直接使用Intent会使模块间耦合严重。为了降低耦合度,一个直观思路是写配置文件来管理所有的组件信息,将这个思路实现得更高级完善,也就是所谓的路由框架(粗浅理解)。常见路由框架如阿里自研的ARouter,就用于解决模块间的界面跳转问题。

路由框架通过注释方式在目标组件添加路由,并维护路由表对路由进行统一管理。举个例子:

target activity:

1
2
@RouterTarget(path = "/test/faceauthentry")
public class FaceAuthEntryActivity extends BaseActivity {

source activity跳转到target Activity:

1
ARouter.getInstance().build("/test/faceauthentry").navigation();

小结

本篇文章记录了个人对ICC的理解,以及对所见过的ICC类型进行总结,主要包括Intent消息传递,非典型ICC,路由框架三类ICC。其中Intent是最常见的组件间通信方式;非典型ICC指那些依赖PendingIntents 和 IntentSenders,可以用于实现ICC的API;路由框架则是现在一种比较流行的界面跳转机制,可以实现模块之间解耦合。

参考文章