赞
踩
一、概述
三、AIDL分类(两类)
1、第一类:声明实现了Parcelable接口的数据类型,以供其他AILD文件使用那些非默认支持的数据类型。
2、第二类:用来定义接口方法,声明要暴露那些接口给客户端调用,定向Tag就是用来标注这些方法的参数值。
四、定向TAG
定向Tag表示在跨进程通信中数据的流向,用于标注方法的参数。分为in,out,inout。in表示由客户端设置,out表示由服务端设置,inout是两者均可设置。此外,如果AIDL方法接口的参数值类型是:基本数据类型、String、CharSequence或者其他AIDL文件定义的方法接口,那么这些参数值的定向 Tag 默认是且只能是 in,所以除了这些类型外,其他参数值都需要明确标注使用哪种定向Tag。
五、明确导包
在AIDL文件中需要明确标明引用到的数据类型所在包名,即使两个文件处在同个包名下。
六、注
客户端的AIDL文件包名需要与服务端的AIDL文件包名一致,否则会报 java.lang.SecurityException:Binder invocation to an incoverect interface。
七、基本使用方法
1.定义AIDL文件,此文件相当于一个协议,定义服务端要实现的方法。
如:
package com.example.aidl;
interface IMyService {
void play();
void pause();
}
2.实现服务端Service:
如:
public class AIDLService extends Service {
private MyBinder mBinder;
@Override
public IBinder onBind(Intent intent) {
mBinder = new MyBinder();
return mBinder; //返回binder对象
}
/*
* 该类继承了IMyService.Stub类而不是extends Binder类。
* IMyService.Stub是Binder的子类。
* 进程内的Service定义MyBinder内部类是继承Binder类。
*/
public class MyBinder extends IMyService.Stub {
@Override
public void play() throws RemoteException {
Log.i(tag, "service 自定义 play()...");
}
@Override
public void pause() throws RemoteException {
Log.i(tag, "service 自定义 pause()...");
}
}
- public class MainActivity extends Activity implements OnClickListener {
- Button btnBind, btnPlay, btnPause;
- IMyService mBinder; // 接口的一个引用
- boolean mIsBind = false; // 绑定值为true,未绑定制为false;
- private ServiceConnection mConn = new ServiceConnection() {
- @Override
- public void onServiceDisconnected(ComponentName name) {
- }
- @Override
- public void onServiceConnected(ComponentName name, IBinder service) {
- /*
- * 获得另一个进程中的Service传递过来的IBinder对象-service,
- * 用IMyService.Stub.asInterface方法转换该对象,这点与进程内的通信不同
- */
- mBinder = IMyService.Stub.asInterface(service);
- mIsBind = true;
- Log.i("MainActivity", "onServiceConnected....");
- }
- };
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- btnBind = (Button) findViewById(R.id.btn_bind);
- btnPlay = (Button) findViewById(R.id.btn_play);
- btnPause = (Button) findViewById(R.id.btn_pause);
- btnBind.setOnClickListener(this);
- btnPlay.setOnClickListener(this);
- btnPause.setOnClickListener(this);
- }
- @Override
- public void onClick(View v) {
- Intent intent = new Intent();
- int btn = v.getId();
- switch (btn) {
- case R.id.btn_bind:
- intent.setAction(Constant.ACTION_AIDL);
- bindService(intent, mConn, BIND_AUTO_CREATE);
- //绑定服务
- break;
- case R.id.btn_play:
- if (mIsBind){
- try {
- mBinder.play(); //调用IMyService接口的方法,服务端的逻辑就可以使用
- } catch (RemoteException e) {
- e.printStackTrace();
- }//调用service中的play()
- }
- break;
- case R.id.btn_pause:
- if(mIsBind){
- try {
- mBinder.pause(); //调用IMyService接口的方法
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- break;
- }
- }
- }
总结:
AIDL的最终效果就是让 IPC的通讯就像调用函数那样简单。自动的帮你完成了参数序列化发送以及解析返回数据的那一系列麻烦。而你所需要做的就是写上一个接口文件,然后利用aidl工具转化一下得到另一个java文件,这个文件在服务和客户端程序各放一份。服务程序继承IxxxxService.Stub 然后将函数接口里面的逻辑代码实现一下。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。