前言
阅读Android源码的过程中,绕不开binder通信,因此记录一二。
Binder基本原理
Binder通信采用C/S架构,以内核空间binder驱动为基础,用户空间ServiceManager管理各种服务,连接Client和Service端。
上图中的ServiceManager是native层的ServiceManager(C++),而不是framework层的ServiceManager(java),binder的实现实际上在native层完成,java是通过Jni调用完成在java层的binder实现。
由于不精通C++,native层的代码实现并不理解。我暂时简单理解如下,binder驱动会拥有一块虚拟内存,用于信息的存储和传递。Client , Service,ServiceManager间的IPC并不是直接通信,他们都是通过与Binder驱动的数据交互完成的。
binder在native层具体的交互过程,暂时无法啃透,推荐文章Binder实现原理
本文着重关注framework层的binder交互的实现和理解,另外后续会关注Aidl的实现和理解。
framework层binder的实现
Server端
1.ServerDemo.java
Server端的运行代码
package src.com.weiyuanfei.serverdemo;
import android.os.Looper;
import android.os.ServiceManager;
public class ServerDemo {
public static void main(String[] args) {
System.out.println("MyService Start");
Looper.prepareMainLooper(); //开启循环执行
android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_FOREGROUND); //设置为前台优先级
ServiceManager.addService("MyService", new MyService());//注册服务
Looper.loop();
}
}```
####2.IMyService.java
IIterface接口方法
package src.com.weiyuanfei.serverdemo;
/**
- Created by weiyuanfei on 17-5-22.
*/
import android.os.IInterface;
import android.os.RemoteException;
public interface IMyService extends IInterface {
static final java.lang.String DESCRIPTOR = "com.weiyuanfei.frameworkBinder.MyServer";//binder通信识别标志
public void sayHello(String str) throws RemoteException;
static final int TRANSACTION_say = android.os.IBinder.FIRST_CALL_TRANSACTION;//设置的transact的code
}
####3.MyService.java
继承binder
package src.com.weiyuanfei.serverdemo;
/**
- Created by weiyuanfei on 17-5-22.
*/
import android.os.Binder;
import android.os.IBinder;
import android.os.Parcel;
import android.os.RemoteException;
public class MyService extends Binder implements IMyService {
public MyService() {
this.attachInterface(this, DESCRIPTOR);
}
@Override
public IBinder asBinder() {
return this;
}
/**
* 将MyService转换为IMyService接口
**/
public static src.com.weiyuanfei.serverdemo.IMyService asInterface(
android.os.IBinder obj) {
if ((obj == null)) {
return null;
}
android.os.IInterface iInterface = obj.queryLocalInterface(DESCRIPTOR);
if (((iInterface != null) && (iInterface instanceof src.com.weiyuanfei.serverdemo.IMyService))) {
return ((src.com.weiyuanfei.serverdemo.IMyService) iInterface);
}
return null;
}
/**
* 服务端,接收远程消息,处理onTransact方法
**/
@Override
protected boolean onTransact(int code, Parcel data, Parcel reply, int flags)
throws RemoteException {
switch (code) {
case INTERFACE_TRANSACTION: {
reply.writeString(DESCRIPTOR);
System.out.println("INTERFACE_TRANSACTION");
return true;
} //检查对端信息
case TRANSACTION_say: {
data.enforceInterface(DESCRIPTOR);///读取指定服务的标识
String str = data.readString();//读取客户端的data
sayHello(str);
reply.writeNoException();//parcel队头写入无异常
return true;
}
}
return super.onTransact(code, data, reply, flags);
}
/**
* 自定义sayHello()方法
**/
@Override
public void sayHello(String str) {
System.out.println("MyService:: Hello, " + str);
}
}
###Client端
####1.ClientDeomo.java
package src.com.weiyuanfei.clientdemo;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.ServiceManager;
public class ClientDemo {
public static void main(String[] args) throws RemoteException {
System.out.println("Client start");
IBinder binder = ServiceManager.getService("MyService"); //获取名为"MyService"的服务,可以理解为服务的binder引用
IMyService myService = new MyServiceProxy(binder); //创建MyServiceProxy对象
myService.sayHello("binder"); //通过MyServiceProxy对象调用接口的方法
System.out.println("Client end");
}
}
####2.IMyService.java
package src.com.weiyuanfei.clientdemo;
/**
- Created by weiyuanfei on 17-5-22.
*/
import android.os.IInterface;
import android.os.RemoteException;
public interface IMyService extends IInterface {
static final java.lang.String DESCRIPTOR = "com.weiyuanfei.frameworkBinder.MyServer";
public void sayHello(String str) throws RemoteException;
static final int TRANSACTION_say = android.os.IBinder.FIRST_CALL_TRANSACTION;
}
####3.MyService.java
package src.com.weiyuanfei.clientdemo;
/**
- Created by weiyuanfei on 17-5-22.
*/
import android.os.IBinder;
import android.os.RemoteException;
public class MyServiceProxy implements IMyService {
private android.os.IBinder mRemote; //
public MyServiceProxy(android.os.IBinder remote) {
mRemote = remote;
}
public java.lang.String getInterfaceDescriptor() {
return DESCRIPTOR;
}
/** **/
@Override
public void sayHello(String str) throws RemoteException {
android.os.Parcel _data = android.os.Parcel.obtain();//获得parcel对象
android.os.Parcel _reply = android.os.Parcel.obtain();
try {
_data.writeInterfaceToken(DESCRIPTOR);//写入binder标志
_data.writeString(str);//写入字串
mRemote.transact(TRANSACTION_say, _data, _reply, 0);
_reply.readException();//在Parcel队头读取,若读取值为异常,则抛出该异常;否则,程序正常运行。
} finally {
_reply.recycle();
_data.recycle();
}
}
@Override
public IBinder asBinder() {
return mRemote;
}
}