Android Binder详细使用教程

Android Binder 使用教程

Binder 是 Android 的核心 IPC (进程间通信) 机制,几乎所有系统服务和应用间的跨进程通信都基于 Binder 实现。本教程将详细介绍 Binder 的使用方法。

1. Binder 基础概念

1.1 Binder 架构

  • 客户端(Client): 发起请求的进程
  • 服务端(Server): 提供服务的进程
  • Service Manager: 管理系统服务的注册与查询
  • Binder驱动: 内核空间的通信桥梁

1.2 核心类

  • IBinder: 基础通信接口
  • IInterface: 定义服务接口
  • Binder: 服务端基类
  • Proxy: 客户端代理类
  • Parcel: 数据容器

2. 定义 AIDL 接口

2.1 创建 AIDL 文件

src/main/aidl 目录下创建 .aidl 文件:

1
2
3
4
5
6
7
// IMyService.aidl
package com.example;

interface IMyService {
    int add(int a, int b);
    String getMessage();
}

2.2 编译生成 Java 文件

Android Studio 会自动生成对应的 Java 接口:

  • IMyService.java: 接口定义
  • IMyService.Stub.java: 服务端基类
  • IMyService.Stub.Proxy.java: 客户端代理

3. 实现服务端

3.1 创建 Service 类

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
public class MyService extends Service {
    private final IBinder mBinder = new MyServiceImpl();
    
    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }
    
    private class MyServiceImpl extends IMyService.Stub {
        @Override
        public int add(int a, int b) {
            return a + b;
        }
        
        @Override
        public String getMessage() {
            return "Hello from Binder Service";
        }
    }
}

3.2 注册 Service

AndroidManifest.xml 中声明:

1
2
3
4
5
6
7
<service 
    android:name=".MyService"
    android:exported="true">
    <intent-filter>
        <action android:name="com.example.MyService" />
    </intent-filter>
</service>

4. 实现客户端

4.1 绑定服务

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
public class MainActivity extends Activity {
    private IMyService mService;
    private boolean mBound = false;
    
    private ServiceConnection mConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            mService = IMyService.Stub.asInterface(service);
            mBound = true;
        }
        
        @Override
        public void onServiceDisconnected(ComponentName name) {
            mBound = false;
        }
    };
    
    @Override
    protected void onStart() {
        super.onStart();
        Intent intent = new Intent("com.example.MyService");
        intent.setPackage("com.example.serviceapp");
        bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
    }
    
    @Override
    protected void onStop() {
        super.onStop();
        if (mBound) {
            unbindService(mConnection);
            mBound = false;
        }
    }
}

4.2 调用远程方法

1
2
3
4
5
6
7
8
9
if (mBound) {
    try {
        int result = mService.add(3, 5);
        String msg = mService.getMessage();
        Log.d("BinderDemo", "Result: " + result + ", Message: " + msg);
    } catch (RemoteException e) {
        e.printStackTrace();
    }
}

5. 高级用法

5.1 传递复杂对象

  1. 实现 Parcelable 接口:
1
2
3
4
5
6
public class MyData implements Parcelable {
    private int id;
    private String name;
    
    // Parcelable实现代码...
}
  1. 在 AIDL 中声明:
1
parcelable MyData;
  1. 在接口中使用:
1
2
3
4
interface IMyService {
    void sendData(in MyData data);
    MyData receiveData();
}

5.2 回调接口

  1. 定义回调 AIDL:
1
2
3
interface ICallback {
    void onEvent(int code, String message);
}
  1. 在服务接口中注册回调:
1
2
3
4
interface IMyService {
    void registerCallback(ICallback cb);
    void unregisterCallback(ICallback cb);
}
  1. 实现回调:
1
2
3
4
5
6
private ICallback mCallback = new ICallback.Stub() {
    @Override
    public void onEvent(int code, String message) {
        // 处理回调
    }
};

6. 注意事项

  1. 线程模型:

    • Binder 调用默认在 Binder 线程池执行
    • UI 相关操作需要切换到主线程
  2. 异常处理:

    • 所有远程调用都可能抛出 RemoteException
    • 需要妥善处理异常情况
  3. 性能优化:

    • 减少跨进程调用次数
    • 批量传输数据
    • 避免传递大数据
  4. 安全性:

    • 验证调用方权限
    • 敏感操作需要权限检查

7. 调试技巧

  1. 使用 adb shell dumpsys activity services 查看服务信息
  2. 检查 Binder 事务大小限制(通常 1MB)
  3. 使用 adb logcat 查看 Binder 相关日志
  4. 测试服务断开重连逻辑

通过以上步骤,您可以实现完整的 Android Binder IPC 通信。Binder 是 Android 系统级 IPC 的核心机制,掌握其使用方法对于开发系统服务和复杂应用至关重要。

Licensed under CC BY-NC-SA 4.0
Built with Hugo
主题 StackJimmy 设计