Android7与Android8中,与AMS进行跨进程通讯方式的转变

184 阅读2分钟

在 Android 系统的演进中,从 Android 7 到 Android 8,与 ActivityManagerService(AMS)通信的方式确实发生了从代理类方式向 AIDL(Android Interface Definition Language)方式的转变,下面为你详细介绍这两种方式以及切换的原因:

Android 7 及以前:代理类方式

原理

在早期的 Android 版本(如 Android 7 及以前),与 ActivityManagerService 通信主要借助代理类。代理类是一种设计模式,它作为 ActivityManagerService 的远程代理存在于客户端进程中。客户端通过调用代理类的方法,将请求发送到系统进程(包含 ActivityManagerService),代理类会负责处理跨进程通信(IPC)的细节,比如将方法调用转换为合适的消息格式并通过 Binder 机制发送到系统进程。

示例代码结构

以下是一个简化的示例来展示这种代理类的概念:

// 客户端调用的代理类
public class ActivityManagerProxy {
    private IBinder mRemote;

    public ActivityManagerProxy(IBinder remote) {
        mRemote = remote;
    }

    public void startActivity(Intent intent) {
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
        try {
            data.writeInterfaceToken(IActivityManager.descriptor);
            intent.writeToParcel(data, 0);
            mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0);
            reply.readException();
        } catch (RemoteException e) {
            e.printStackTrace();
        } finally {
            data.recycle();
            reply.recycle();
        }
    }
}

在这个示例中,ActivityManagerProxy 是客户端使用的代理类,它通过 Binder 进行跨进程通信,将 startActivity 的请求发送到 ActivityManagerService

Android 8 及以后:AIDL 方式

原理

AIDL 是 Android 提供的一种接口定义语言,用于定义客户端和服务端之间的通信接口。在 Android 8 及以后的版本中,与 ActivityManagerService 通信采用 AIDL 方式。开发者只需要定义一个 AIDL 文件,描述客户端和服务端之间的接口方法,然后 Android 工具会自动生成相应的 Java 代码,包括代理类和 Stub 类。客户端通过调用代理类的方法,代理类会将请求封装并通过 Binder 发送到服务端的 Stub 类,Stub 类再调用实际的 ActivityManagerService 方法进行处理。

示例代码结构

  1. 定义 AIDL 文件(例如 IActivityManager.aidl

// IActivityManager.aidl
package android.app;

import android.content.Intent;

interface IActivityManager {
    int startActivity(in Intent intent);
}
  1. Android 工具会自动生成相关的 Java 代码
    生成的代码包含 IActivityManager 接口、Stub 类(服务端实现)和代理类(客户端使用)。客户端可以通过如下方式使用:

// 获取 AIDL 接口的代理对象
IActivityManager am = IActivityManager.Stub.asInterface(ServiceManager.getService("activity"));
// 调用方法
am.startActivity(intent);

切换的原因

  • 代码生成和维护的便利性:使用 AIDL,Android 工具会自动生成跨进程通信所需的代码,减少了手动编写代码的工作量,降低了出错的可能性,同时也方便了代码的维护和更新。
  • 标准化和可读性:AIDL 提供了一种标准化的方式来定义跨进程接口,使得代码更加清晰和易于理解,不同开发者之间的协作也更加顺畅。
  • 兼容性和扩展性:AIDL 支持复杂的数据类型和参数传递,能够更好地适应 Android 系统不断发展的需求,提高了系统的兼容性和扩展性。