一、 Binder概述
1.1 为什么要用binder
- 出于安全性、稳定性和内存管理的考虑,Android的应用和系统服务运行在分离的进程中,但是它们之间需要通信和共享数据
- 避免传统IPC开销和服务拒绝的问题
- android的库不支持System V 的IPC
- Binder加入了对象引用的引用计数器,消亡提醒机制。当一个Binder服务没有任何终端引用时,它的所有者可以自动提醒它去处理自己
- Binder通过UID/PID来分辨发送者和接受者(对于安全很重要)
但是:
- Binder不支持RPC,只有本地
- 客户端和服务端基于消息通信,不适用于流
- 不符合POSIX标准
1.2 binder通信流程
客户端使用服务
进程之间无法进行直接通信,所以通过Binder驱动
客户端和服务端不需要了解binder协议,所以使用代理和存根
客户端不想要知道正在使用IPC,也不关心binder和代理,所以,需要管理对象进行抽象
但是客户端怎样获取它想要通信的服务的handle,只需要问问sevicemanager(Context Manager),服务是否已经注册
最后,我们看下总体的架构
二 、 AIDL示例
使用aidl实现跨进程的加减法
2.1 服务端
新建android工程,创建包com.realize.calc.aidl,新建文件ICalcAIDL.aidl,内容如下
package com.realize.calc.aidl;
interface ICalcAIDL
{
int add(int x , int y);
int min(int x , int y );
}
创建包com.realize.lizijun.binder_server,新建服务CalcService.java,内容如下
package com.realize.lizijun.binder_server;
import com.realize.calc.aidl.ICalcAIDL;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
public class CalcService extends Service
{
private static final String TAG = "server";
public void onCreate()
{
Log.e(TAG, "onCreate");
}
public IBinder onBind(Intent t)
{
Log.e(TAG, "onBind");
return mBinder;
}
public void onDestroy()
{
Log.e(TAG, "onDestroy");
super.onDestroy();
}
public boolean onUnbind(Intent intent)
{
Log.e(TAG, "onUnbind");
return super.onUnbind(intent);
}
public void onRebind(Intent intent)
{
Log.e(TAG, "onRebind");
super.onRebind(intent);
}
private final ICalcAIDL.Stub mBinder = new ICalcAIDL.Stub()
{
@Override
public int add(int x, int y) throws RemoteException
{
return x + y;
}
@Override
public int min(int x, int y) throws RemoteException
{
return x - y;
}
};
}