最近在看Binder的实现机制,但是感觉总不是很清晰,所以想理解他的实现原理,先暂时学会怎么使用。Binder是android中的一种进程间通信机制,

android的底层是Linux系统,Linux系统中进程间通信方式主要有以下几种:

1、socket,即客户端服务器模式。所以我们客户端程序通过socket和服务器端程序进行通信,其实就是进程间通信的一个实例。

2、传统的消息队列机制

3、共享内存机制

4、信号量机制

在android系统中,由于安全性等一些其他因素影响,所以android的开发者们实现了另外一种进程间通信方式Binder,android中所有的进程间通信方式

都是通过Binder以及以上4种方式来实现的,ContentProvider实现的进程间数据共享方式就是通过共享内存以及Binder方式来实现进程间通信的,具体

的详细解释可以参考老罗的这篇博客:http://blog.csdn.net/luoshengyang/article/details/6946067。android的RPC机制(远程过程调用)也是通过Binder

机制来实现的,RPC其实就是IPC机制的一种实现方式,IPC即Interprocess communication 进程间通信,实现IPC有很多方式,但是有时候我们并不满

足于仅仅实现数据通信,有时候我们还需要去调用其它进程间的方法或对象,这时就需要RPC机制了,而android中就是通过AIDL来实现这样一种RPC

机制。具体关于RPC的定义可以google去看wiki的介绍。下面我们就来看看android的RPC机制是怎样通过AIDL(接口定义语言)来实现进程间的方法或对

象调用的。

一 、新建远程调用app(即新建一个进程),实现远程方法调用

1、新建一个AIDL文件RemoteServiceAidl.aidl,定义几个方法,分别以基本类型数据和对象作为参数。定义好之后会在工程的gen目录下生成相同的包

名以及相同文件名的java文件RemoteServiceAidl.java,他的代码我就不贴出来了。

package com.lonuery.aidl;import com.lonuery.remote.GroupInfo;interface RemoteServiceAidl {int calculate(int num1,int num2);void checkInfo(String str,double data);String save(in GroupInfo groupInfo);}

2、由于AIDL中传递基本数据类型和对象的方式不同,传递对象就必须实现Parcelable接口,接下来定义GroupInfo类

public class GroupInfo implements Parcelable{String name,groupId,memCount;public GroupInfo(String name,String groupId,String memCount){this.name = name;this.groupId = groupId;this.memCount = memCount;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getGroupId() {return groupId;}public void setGroupId(String groupId) {this.groupId = groupId;}public String getMemCount() {return memCount;}public void setMemCount(String memCount) {this.memCount = memCount;}@Overridepublic int describeContents() {return 0;}@Overridepublic void writeToParcel(Parcel parcel, int arg1) {//参数的写入是什么顺序,那么下面参数的读取就应该是什么顺序。参数的写入顺序不对,会导致读取的参数顺序不对parcel.writeString(this.name);parcel.writeString(this.groupId);parcel.writeString(this.memCount);}//如果要传递对象那么这个类中就必须创建一个名字为CREATOR的Creator对象。public static final Parcelable.Creator<GroupInfo> CREATOR = new Parcelable.Creator<GroupInfo>() {@Overridepublic GroupInfo createFromParcel(Parcel parcel) {return new GroupInfo(parcel.readString(), parcel.readString(), parcel.readString());}@Overridepublic GroupInfo[] newArray(int size) {return new GroupInfo[size];}};}

3、在GroupInfo.java相同包下定义GroupInfo.aidl文件。

package com.lonuery.remote;parcelable GroupInfo;

3、实现RemoteServiceAidl.Stub类,并且定义一个Service以供其他程序来远程绑定,返回Stub的对象。

public class RemoteService extends Service{String TAG = "RemoteService";AidlImpl aidlService = new AidlImpl();@Overridepublic IBinder onBind(Intent arg0) {Log.v(TAG, "onBind");return aidlService;}class AidlImpl extends RemoteServiceAidl.Stub{@Overridepublic int calculate(int num1, int num2) throws RemoteException {int result = num1*num2;return result;}@Overridepublic void checkInfo(String str, double data) throws RemoteException {if(str!=null){Log.v("checkInfo", "输出");}}@Overridepublic String save(GroupInfo groupInfo) throws RemoteException {String str = null;if(groupInfo!=null){if(groupInfo.getGroupId().equals("电话")){str = "地方金额1";}else if(groupInfo.getMemCount().equals("电话")){str = "地方金额2";}else if(groupInfo.getName().equals("电话")){str = "地方金额3";}}return str;}}}

二、新建调用app即新建调用进程

1、在新建的调用app中新建和RemoteServiceAidl.aidl相同的包名,并将RemoteServiceAidl.aidl复制到这个包中。同样,在gen目录下也会自动生成

RemoteServiceAidl.java的文件。

2、新建和GroupInfo.java相同的包名并将GroupInfo.java和GroupInfo.aidl文件复制到此包中。

3、绑定远程服务,利用远程服务对象,调用远程方法。

public class MainActivity extends Activity implements OnClickListener{Button btn1;RemoteServiceAidl remoteService;TextView tv;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);btn1 = (Button)findViewById(R.id.button1);btn1.setOnClickListener(this);tv = (TextView)findViewById(R.id.textView1);bindService(new Intent(RemoteServiceAidl.class.getName()), connection, Context.BIND_AUTO_CREATE);}@Overridepublic void onClick(View view) {if(view.getId()==R.id.button1){try {int result=0;GroupInfo info = new GroupInfo("", "电话", "");String str=null;try {result = remoteService.calculate(6, 8);str = remoteService.save(info);} catch (DeadObjectException e) {e.printStackTrace();}tv.setText("result:"+result);String text = tv.getText().toString() + "Id:"+str;tv.setText(text);} catch (RemoteException e) {e.printStackTrace();}}}@Overrideprotected void onDestroy() {unbindService(connection);super.onDestroy();}private ServiceConnection connection = new ServiceConnection() {@Overridepublic void onServiceDisconnected(ComponentName arg0) {remoteService = null;}@Overridepublic void onServiceConnected(ComponentName arg0, IBinder binder) {remoteService = RemoteServiceAidl.Stub.asInterface(binder);}};}

4、在AndroidManifest.xml中对所创建的服务进行注册。

接下来我们分别安装远程app,和调用app,来看一下效果。

好了android中aidl的使用实例就完成了,接下来我们总结一下:

1、RemoteService只是一个代理的角色,他的作用就是让其他的进程来绑定他,然后通过他进行远程方法调用,真正的调用其实是在

RemoteServiceAidl.Stub的实现类AidlImpl中实现的。

2、将AidlImpl类的对象返回给RemoteService的绑定接口onBind,远程调用就是通过这个接口来获取AidlImpl对象,继而实现方法的调用。

3、远程进程通过bindService方法绑定远程服务RemoteService。

实例已经上传到csdn上http://download.csdn.net/detail/zkw12358/7362967

更多相关文章

  1. 1、android orm之greendao
  2. Android(安卓)开发之详解 IPC 进程通信
  3. Android(安卓)源码分析 - 事件分发机制
  4. Android(安卓)进阶10:进程通信之 Messenger 使用与解析
  5. 雷电android game学习笔记(1)
  6. Handler+Message+MessageQuque+Looper 异步加载类 消息处理机制
  7. [Android笔记] 关于 AppWidget 动态更新:RemoteViews 更新缓慢&内
  8. Android(安卓)studio 下的aidl编程实现Android的夸进程间通信
  9. 为 Android(安卓)添加 Java 层服务(二)

随机推荐

  1. Android中自定义ProgressBar
  2. 逆向工具/反编译工具 集合
  3. Android 权限被拒绝,跳转至权限设置界面
  4. AndroidManifest中activity属性设置大全
  5. android:HttpClient请求(get、post)
  6. Android(安卓)ListView控件使用
  7. Android APP无法接收开机广播
  8. OpenWrt上运行Android OS
  9. ScrollView嵌套webview因焦点问题导致自
  10. Android 开发判断用户是否安装微信和QQ并