Android 中的Binder跨进程通信机制与AIDL
2016-11-15 18:48
567 查看
如果对进程、线程概念还很懵懂的同学可以看一下之前发表的一篇博客,里面是基础概念:
IPC进程间通信/跨进程通信
http://blog.csdn.net/github_33304260/article/details/52895331
Socket开销大且效率不高;管道和队列拷贝次数过多,而且传统跨进程通信手段安全性不高,接收方无法识别UID、PID,对于移动设备的安全性和效率考虑设计出来Binder。那么Binder这么好究竟是什么东西呢?
Binder Client相当于客户端,Binder Server相当于服务器, ServerManager相当于DNS服务器,Binder Driver 相当于一个路由器。
Binder Driver位于内核空间,主要负责Binder通信的建立,以及其在进程见得传递和Binder引用计数管理/数据包的传输等。Binder Server与 Binder Client之间的跨进程通信则通过Binder Driver转发。对于 Binder Client只需要知道自己要使用Binder的名字以及该binder实体在 Server Manager中的0号引用即可。ServerManager就是一个标准的BinderServer,并且在Android中约定其在Binder通信过程中唯一标识符永远是0。那说了这么多到底怎么进行跨进程呢?
下面看一下具体demo
github地址:
https://github.com/libin7278/DesignModle
新建一个AIDl
然后在build/generated可以看到生成的IBackAidl.java
这里贴出一部分
这下就能看到两个进程了!
不过要注意:
1)
2)
必须显性,不然在安卓5.0会报错!!!!!
IPC进程间通信/跨进程通信
http://blog.csdn.net/github_33304260/article/details/52895331
为什么需要跨进程通信?
答:两个对象能直接互相访问的前提是两个对象在相同的内存地址空间中,如果两个对象那个在两个不同的进程中,比如ActivityManager和ActivityManagerService,不能直接互调需要跨进程技术,所以需要跨进程通信。那么问题来了,已有那么多跨进程手段,如上一篇讲的管道,Socket等,为什么还要大费周折弄一个Binder?为什么在Android中使用Binder进行跨进程通信?
答:之说以这么大费周折,那肯定有Binder的过人之处。Socket开销大且效率不高;管道和队列拷贝次数过多,而且传统跨进程通信手段安全性不高,接收方无法识别UID、PID,对于移动设备的安全性和效率考虑设计出来Binder。那么Binder这么好究竟是什么东西呢?
Binder是什么?
答:BInder是由四个模块组成,Binder Driver 、Binder Client、Binder Server、 Server Manager。Binder Client相当于客户端,Binder Server相当于服务器, ServerManager相当于DNS服务器,Binder Driver 相当于一个路由器。
Binder Driver位于内核空间,主要负责Binder通信的建立,以及其在进程见得传递和Binder引用计数管理/数据包的传输等。Binder Server与 Binder Client之间的跨进程通信则通过Binder Driver转发。对于 Binder Client只需要知道自己要使用Binder的名字以及该binder实体在 Server Manager中的0号引用即可。ServerManager就是一个标准的BinderServer,并且在Android中约定其在Binder通信过程中唯一标识符永远是0。那说了这么多到底怎么进行跨进程呢?
如何使用Binder进行跨进程通信呢?
答: Binder Driver 和ServerManager是底层的没必要实现,只需实现Binder Client和Binder Server。但是Binder Server代码在C中实现,并且逻辑复杂,所以Android提供了一个简单的方式–AIDL–来生成一个Binder Server。下面看一下具体demo
github地址:
https://github.com/libin7278/DesignModle
新建一个AIDl
// IBackAidl.aidl package com.mvp.libin.aidl_example; // Declare any non-default types here with import statements interface IBackAidl { /** * 开户 * @param name * @param password * @return */ String OpenAccount(String name,String password); /** * 存钱 * @param money * @param account * @return */ String saveMoney(int money,String account); /** * 取钱 * @param money * @param account * @param password * @return */ String tackMoney(int money,String account,String password); /** * 销户 * @param account * @param password * @return */ String closeAccount(String account,String password); }
然后在build/generated可以看到生成的IBackAidl.java
这里贴出一部分
/** * 开户 * @param name * @param password * @return */ @Override public java.lang.String OpenAccount(java.lang.String name, java.lang.String password) throws android.os.RemoteException { android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); java.lang.String _result; try { _data.writeInterfaceToken(DESCRIPTOR); _data.writeString(name); _data.writeString(password); mRemote.transact(Stub.TRANSACTION_OpenAccount, _data, _reply, 0); _reply.readException(); _result = _reply.readString(); } finally { _reply.recycle(); _data.recycle(); } return _result; } /** * 存钱 * @param money * @param account * @return */ @Override public java.lang.String saveMoney(int money, java.lang.String account) throws android.os.RemoteException { android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); java.lang.String _result; try { _data.writeInterfaceToken(DESCRIPTOR); _data.writeInt(money); _data.writeString(account); mRemote.transact(Stub.TRANSACTION_saveMoney, _data, _reply, 0); _reply.readException(); _result = _reply.readString(); } finally { _reply.recycle(); _data.recycle(); } return _result; } /** * 取钱 * @param money * @param account * @param password * @return */ @Override public java.lang.String tackMoney(int money, java.lang.String account, java.lang.String password) throws android.os.RemoteException { android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); java.lang.String _result; try { _data.writeInterfaceToken(DESCRIPTOR); _data.writeInt(money); _data.writeString(account); _data.writeString(password); mRemote.transact(Stub.TRANSACTION_tackMoney, _data, _reply, 0); _reply.readException(); _result = _reply.readString(); } finally { _reply.recycle(); _data.recycle(); } return _result; } /** * 销户 * @param account * @param password * @return */ @Override public java.lang.String closeAccount(java.lang.String account, java.lang.String password) throws android.os.RemoteException { android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); java.lang.String _result; try { _data.writeInterfaceToken(DESCRIPTOR); _data.writeString(account); _data.writeString(password); mRemote.transact(Stub.TRANSACTION_closeAccount, _data, _reply, 0); _reply.readException(); _result = _reply.readString(); } finally { _reply.recycle(); _data.recycle(); } return _result; } } static final int TRANSACTION_OpenAccount = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0); static final int TRANSACTION_saveMoney = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1); static final int TRANSACTION_tackMoney = (android.os.IBinder.FIRST_CALL_TRANSACTION + 2); static final int TRANSACTION_closeAccount = (android.os.IBinder.FIRST_CALL_TRANSACTION + 3); } /** * 开户 * @param name * @param password * @return */ public java.lang.String OpenAccount(java.lang.String name, java.lang.String password) throws android.os.RemoteException; /** * 存钱 * @param money * @param account * @return */ public java.lang.String saveMoney(int money, java.lang.String account) throws android.os.RemoteException; /** * 取钱 * @param money * @param account * @param password * @return */ public java.lang.String tackMoney(int money, java.lang.String account, java.lang.String password) throws android.os.RemoteException; /** * 销户 * @param account * @param password * @return */ public java.lang.String closeAccount(java.lang.String account, java.lang.String password) throws android.os.RemoteException; }
package com.mvp.libin.aidl_example; import android.os.Binder; import java.util.UUID; /** * Created by libin on 16/11/16. */ public class BanklBinder extends IBackAidl.Stub{ @Override public String OpenAccount(String name, String password) { return name+"开户成功"+ UUID.randomUUID().toString(); } @Override public String saveMoney(int money, String account) { return "账户:"+account+"存入"+money+"人民币"; } @Override public String tackMoney(int money, String account, String password) { return "账户:"+account+"取出"+money+"人民币"; } @Override public String closeAccount(String account, String password) { return "账户:"+account+"销户"; } } //===================================>下面是本地服务 /* public class BanklBinder extends Binder implements IBank { @Override public String OpenAccount(String name, String password) { return name+"开户成功"+ UUID.randomUUID().toString(); } @Override public String saveMoney(int money, String account) { return "账户:"+account+"存入"+money+"人民币"; } @Override public String tackMoney(int money, String account, String password) { return "账户:"+account+"取出"+money+"人民币"; } @Override public String closeAccount(String account, String password) { return "账户:"+account+"销户"; } } */
package com.mvp.libin.aidl_example; import android.app.Service; import android.content.Intent; import android.os.IBinder; import android.support.annotation.Nullable; /** * Created by libin on 16/11/16. */ public class BankService extends Service { @Nullable @Override public IBinder onBind(Intent intent) { return new BanklBinder(); } } //====================================> /** * 这里是模拟 所以可以把BankService看做 Binder Server * 现在接口有了,服务端也有了,接下来就是客户端了 * */
package com.mvp.libin.aidl_example; import android.content.ComponentName; import android.content.Intent; import android.content.ServiceConnection; import android.os.IBinder; import android.os.RemoteException; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.TextView; public class MainActivity extends AppCompatActivity { private IBackAidl mBanklBinder; //服务端的Server对象 private TextView tv; //用于绑定Server的ServerConnection对象 private ServiceConnection serviceConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { mBanklBinder =IBackAidl.Stub.asInterface(service); } @Override public void onServiceDisconnected(ComponentName name) { } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); tv = (TextView) findViewById(R.id.tv); Intent intent = new Intent(this,BankService.class); intent.setAction("cn.augest.test.aidl.bank"); bindService(intent, serviceConnection, BIND_AUTO_CREATE); init(R.id.b1); init(R.id.b2); init(R.id.b3); init(R.id.b4); } @Override protected void onDestroy() { super.onDestroy(); unbindService(serviceConnection); } private void init(int id) { Button button = (Button) findViewById(id); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { switch (v.getId()) { case R.id.b1: try { tv.setText(mBanklBinder.OpenAccount("libin", "123456")); } catch (RemoteException e) { e.printStackTrace(); } break; case R.id.b2: try { tv.setText(mBanklBinder.saveMoney(12345, "libin")); } catch (RemoteException e) { e.printStackTrace(); } break; case R.id.b3: try { tv.setText(mBanklBinder.tackMoney(123,"libin", "123456")); } catch (RemoteException e) { e.printStackTrace(); } break; case R.id.b4: try { tv.setText(mBanklBinder.closeAccount("libin", "123456")); } catch (RemoteException e) { e.printStackTrace(); } break; } } }); } }
这下就能看到两个进程了!
不过要注意:
1)
android:process="cn.aigestudio.BinderServer"必须加入这个 才能新开启线程 上一篇已经讲过
2)
Intent intent = new Intent(this,BankService.class); intent.setAction("cn.augest.test.aidl.bank"); bindService(intent, serviceConnection, BIND_AUTO_CREATE);
必须显性,不然在安卓5.0会报错!!!!!
相关文章推荐
- 从AIDL开始谈Android进程间Binder通信机制
- 从AIDL开始谈Android进程间Binder通信机制
- 从AIDL开始谈Android进程间Binder通信机制
- 从AIDL开始谈Android进程间Binder通信机制
- 从AIDL开始谈Android进程间Binder通信机制
- Android 进程通信-- Binder机制
- Android进程间的通信 - IPC(机制)Binder的原理和源码阅读
- Android跨进程通信之AIDL机制和广播机制的异同
- Android Binder机制实现进程间数据交换(不使用aidl实现)
- Android 进程通信机制之 AIDL
- Android 进程通信机制之 AIDL
- Android系统分析之AIDL跨进程通信机制的使用和原理分析
- Android IPC机制(三)——利用AIDL实现跨进程通信
- Linux与android进程间的通信及android Binder机制详解
- Android进程间的通信 - IPC(机制)Binder的原理和源码阅读
- Android之进程通信机制(下)(AIDL,Messenger,Socket)
- Android中的Binder跨进程通信机制
- Aidl跨进程通信机制-android学习之旅(87)
- Android 进程通信机制之 AIDL
- Aidl跨进程通信机制-android学习之旅(87)