比较全面的bind讲解
java编写binder服务实例
https://www.cnblogs.com/winfu/p/7521372.html
1.编写AIDL 文件
IHelloService.aidl:
/** {@hide} */
interface IHelloService
{
void sayhello();
int sayhello_to(String name);
}
1.把 IHelloService.aidl 放入 frameworks/base/core/java/android/os
2.修改 frameworks/base/Android.mk 添加一行
core/java/android/os/IVibratorService.aidl \
+ core/java/android/os/IHelloService.aidl \
3. 编译/framework/base
4.系统自动生成IHelloService.java
public interface IHelloService extends android.os.IInterface
{
public static abstract class Stub extends android.os.Binder implements IHelloService{
private static final java.lang.String DESCRIPTOR = "IHelloService";
public Stub()
{
this.attachInterface(this, DESCRIPTOR);
}
public static IHelloService asInterface(android.os.IBinder obj)
{ ... ...
return new IHelloService.Stub.Proxy(obj);
}
@Override public android.os.IBinder asBinder()
@Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) ...
{
switch (code)
{
case INTERFACE_TRANSACTION:
case TRANSACTION_sayhello:
case TRANSACTION_sayhello_to:
}
}
private static class Proxy implements IHelloService
static final int TRANSACTION_sayhello = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
static final int TRANSACTION_sayhello_to = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
}
public void sayhello() throws android.os.RemoteException;
public int sayhello_to(java.lang.String name) throws android.os.RemoteException;
}
IHelloService.java 的结构为:
1.名字为IHelloService 的interface:
2.IHelloService 这个interface 中有一个继承Binder 的抽象类stub
IHelloService.aidl 中已经定义好的service 中的几个函数的虚函数
public interface IHelloService extends android.os.IInterface
{
public static abstract class Stub extends android.os.Binder implements IHelloService ...
public void sayhello() throws android.os.RemoteException;
public int sayhello_to(java.lang.String name) throws android.os.RemoteException;
}
2.HelloService.java
import android.util.Slog;
public class HelloService extends IHelloService.Stub {
private static final String TAG = "HelloService";
... ...
public void sayhello() throws android.os.RemoteException {
... ...
}
public int sayhello_to(java.lang.String name) throws android.os.RemoteException {
... ...
}
}
1. HelloService.java 继承 IHelloService.Stub 这个内部类;
2. HelloService.java 中复写 之前在IHelloService.aidl 中定义好的函数
3.Client端代码
import android.util.Slog;
import android.os.ServiceManager;
import android.os.IBinder;
public class TestClient {
public static void main(String args[])
{
if (args[0].equals("hello"))
{
/* 1. getService */
IBinder binder = ServiceManager.getService("hello");
IHelloService svr = IHelloService.Stub.asInterface(binder);
svr.sayhello();
int cnt = svr.sayhello_to(args[1]);
}
}
}
总结:
1.自己先写一个IHelloService.aidl ,系统编译后生成IHelloService.java
2.IHelloService.java是一个接口,其中定义了一个继承了binder 的抽象的 内部类stub,stub中实现了在IHelloService.aidl中定义方法的实现:将需要传输的数据打包为Parcel 类型,调用super.onTransact传输出去。
3.内部类stub中定义了一个实现了IHelloService接口的内部类proxy,proxy中实现了之前定义方法在client端的实现:初始化Parcel,调用mRemote.transact 发送出去。
4.内部类stub 中定义了一个返回 stub中内部类proxy类 的函数asInterface()
5.HelloService 继承IHelloService.stub
6.client端通过ServiceManager.getService("hello")得到IBinder 对象,传入到IHelloService.stub.asInterface() 这个静态方法中获取IHelloService对象,就可以直接调用函数了。
=========================================================================================
https://www.jianshu.com/p/adaa1a39a274
* Parcel
Parcel是一个容器,主要就是用来进行IPC通信的。
1.Parcel的获取 :
Parcel parcle = Parcel.Obtain();
或者
new Parcel();
2.Parcel 传入数据
parcel.writeInt(int val); // 传入Int 型数据
parcel.writeString(String val); //传入String 型 数据
3.Parcel 获取数据
private PrintJobInfo(@NonNull Parcel parcel) {
.. .. ..
mLabel = parcel.readString();
mState = parcel.readInt();
.. .. ..
1. 如何确定目标binder 实体,唤醒进程/线程
binder_proc 结构体
struct binder_proc {
struct hlist_node proc_node;
struct rb_root threads;
struct rb_root nodes;
struct rb_root refs_by_desc;
struct rb_root refs_by_node;
... ...
struct list_head todo;
wait_queue_head_t wait;
... ...
};
nodes : Binder实体在内核中对应的数据结构
binder_node : 记录进程相关的binder_proc
1.SM.addService(XXXservice) ,将XXXservice 对应的binder_ref 放入SM 的binder_ref
2.SM.getService(XXXservice),查询SM 的binder_ref,将XXXservice 对应的binder_ref返回给client
3.client将binder_transaction事物插入到XXXservice 的binder_proc待处理队列
2.Binder传输数据的大小限制
ProcessState类中,限制每次传输大小不超过4M
3.系统服务与bindService服务的区别
1.系统服务:通过SM.addService 添加的service,由ServiceManager 进行管理
2.BinderService:通过Activity的startService启动,Service 只是一个封装,主要是Binder服务实类,不是ServiceManager管理,是AMS 在管理;Activity.binderService添加的service 无法被SM.getService 获取到;
3.BinderService是去ActivityManagerService中去查找相应的Service组件,最终会将Service内部Binder的句柄传给Client。
4.Binder请求的同步与异步
5.Binder协议中BC_TRANSACTION与BR_TRANSACTION
BC与BR主要是标志数据及Transaction流向;
BC_TRANSACTION从用户空间流向内核
BR_TRANSACTION从内核流线用户空间