Android AIDL和Binder 简单分析
来源:互联网 发布:什么软件上youtube 编辑:程序博客网 时间:2024/05/16 00:53
AIDL使用方法:
在AIDLService中创建aidl文件在aidl文件中创建想要创建的接口,之后将.java文件改成.aidl文件重新编译项目.
创建service类在这个类中创建这个接口的对象实现对应的方法如下图:
public class ControlerService extends Service { private final IController.Stub binder = new IController.Stub() { @Override public int addFun(int m, int n) throws RemoteException { return m+n; } }; @Override public void onCreate() { super.onCreate(); } @Override public int onStartCommand(Intent intent, int flags, int startId) { return super.onStartCommand(intent, flags, startId); } @Nullable @Override public IBinder onBind(Intent intent) { return binder; }}之后在AIDLClient这个工程中创建同样的aidl文件夹和同样的aidl文件,之后通过bindService绑定服务就可以实现两个进程间的通信了.
public class MainActivity extends AppCompatActivity { private IController controller = null; private ServiceConnection myConn = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { controller = IController.Stub.asInterface(service); Log.e(MainActivity.class.getName(), "绑定成功"); } @Override public void onServiceDisconnected(ComponentName name) { } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } public void bindService(View view) { //绑定服务 Intent intent = new Intent("com.zfr.aidlservice.ControllerService"); intent.setPackage("com.zengfanrui.practice.learnaidl"); bindService(intent, myConn,BIND_AUTO_CREATE); } public void addFun(View view) { if (controller == null) { return; } try { int i = controller.addFun(1, 2); Toast.makeText(this, "" + i, Toast.LENGTH_SHORT).show(); } catch (RemoteException e) { e.printStackTrace(); } }}如上就实现了两个进城之间的通信了
现在分析一下这两个进程之间是如何实现通信的,这个时候就要使用到Binder,对于Binder本人了解的也不是很明白,个人认为Binder就是一个关联者(或者是中间者)用于协调Client和Service首先来看一下Android对.aidl文件所生成的代码
public interface IController extends android.os.IInterface{/** Local-side IPC implementation stub class. */public static abstract class Stub extends android.os.Binder implements com.zengfanrui.aidlserver.IController{private static final java.lang.String DESCRIPTOR = "com.zengfanrui.aidlserver.IController";/** Construct the stub at attach it to the interface. */public Stub(){this.attachInterface(this, DESCRIPTOR);}/** * Cast an IBinder object into an com.zengfanrui.aidlserver.IController interface, * generating a proxy if needed. */public static com.zengfanrui.aidlserver.IController asInterface(android.os.IBinder obj){if ((obj==null)) {return null;}android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);if (((iin!=null)&&(iin instanceof com.zengfanrui.aidlserver.IController))) {return ((com.zengfanrui.aidlserver.IController)iin);}return new com.zengfanrui.aidlserver.IController.Stub.Proxy(obj);}@Override public android.os.IBinder asBinder(){return this;}@Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException{switch (code){case INTERFACE_TRANSACTION:{reply.writeString(DESCRIPTOR);return true;}case TRANSACTION_addFun:{data.enforceInterface(DESCRIPTOR);int _arg0;_arg0 = data.readInt();int _arg1;_arg1 = data.readInt();int _result = this.addFun(_arg0, _arg1);reply.writeNoException();reply.writeInt(_result);return true;}}return super.onTransact(code, data, reply, flags);}private static class Proxy implements com.zengfanrui.aidlserver.IController{private android.os.IBinder mRemote;Proxy(android.os.IBinder remote){mRemote = remote;}@Override public android.os.IBinder asBinder(){return mRemote;}public java.lang.String getInterfaceDescriptor(){return DESCRIPTOR;}@Override public int addFun(int m, int n) throws android.os.RemoteException{android.os.Parcel _data = android.os.Parcel.obtain();android.os.Parcel _reply = android.os.Parcel.obtain();int _result;try {_data.writeInterfaceToken(DESCRIPTOR);_data.writeInt(m);_data.writeInt(n);mRemote.transact(Stub.TRANSACTION_addFun, _data, _reply, 0);_reply.readException();_result = _reply.readInt();}finally {_reply.recycle();_data.recycle();}return _result;}}static final int TRANSACTION_addFun = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);}public int addFun(int m, int n) throws android.os.RemoteException;}Binder机制是由三个重要的部分组成的 Binder驱动,Binder服务端和Binder客户端,在Binder服务启动的之后服务会自动的将自己"送给"Binder驱动,Binder驱动会将这个服务记录,个人认为就是添加服务表中,之后在Binder客户端获取到了Binder对象之后
通过Binder对象发送调用某个方法的消息实际上是将这个消息传递给Binder驱动,Binder驱动会去对应的表中找到这个Binder服务,调这个服务对应的方法.
Binder服务在一开始启动的时候Binder就会调用transact()这个方法调用这个方法之后会去执行onTransact()这个方法,执行这个方法的时候就会将服务添加到驱动中,从上面的代码可以看到内部类Stub继承了Binder并且实现了我们自己定义的接口
这个Stub类重写了onTransact()方法所以在Binder服务刚刚启动的时候会执行Stub重写的onTransact将DESCRIPTOR通过writeString写进Binder驱动中
Binder客户端在调用Binder服务端方法的时候会通知Binder驱动客户端传递过来的数据是属于哪个服务端的并将数据写进内存中之后会调用transact方法,将客户端想要调用的方法的标志和参数传入,这时候Binder驱动就会找到对应的Service和对应的方法将参数传递过去并且等待Service将结果返回.
这篇文章只是简单的分析了一下Binder的执行过程,关于Binder机制还有很多需要了解的地方
想要更深的理解Binder 请看罗升阳大神的博客
点击打开链接
- Android AIDL和Binder 简单分析
- android进程间通讯流程分析:使用 Binder和AIDL
- android service binder 和AIDL
- Android IPC、Binder和AIDL
- 简单理解Android Binder通信(AIDL)
- Android aidl 案例分析Binder机制
- Android AIDL简单分析
- aidl涉及的Binder框架流程简单分析
- android Binder与AIDL
- Binder-基础知识和AIDL
- AIDL和Binder图解
- Binder机制和AIDL
- AIDL 和binder 原理
- Android aidl Binder框架浅析
- Android aidl Binder框架浅析
- Android aidl Binder框架浅析
- Android aidl Binder框架浅析
- Android aidl Binder框架浅析
- ECMAScript对象--整理
- [LeetCode]581. Shortest Unsorted Continuous Subarray
- C++——模版:类模版
- Cookie与Session的区别
- 回顾接口
- Android AIDL和Binder 简单分析
- 指定日期往后延多少天(android)
- windows环境下IDEA运行spark程序出现的异常问题
- 利用FRIDA攻击Android应用程序(三)
- 【坑爹微信】总有一款接口能坑你到吐血 --- 微信开发经验录
- PHP flush 失效问题 (实时显示)
- 安装软件:/lib/ld-linux.so.2: bad ELF interpreter 解决
- 不能修改"System Roots" 钥匙串
- Java随机生成身份证号码