标签:android aidl binder enforceinterface
一、AIDL是什么?
AIDL(Android Interface Definition Language)是Android接口定义语言,用于进程间的通信(IPC),它能实现让多个应用程序组件之间与某个Service进行跨进程通信,从而实现多个应用程序共享一个服务的功能。
二、为什么要通过AIDL进行IPC通信?
系统为一个应用分配一个进程,进程运行在自己的内存空间,一个进程不能直接访问另外一个进程,如果要进程间的通信,需要通过AIDL,AIDL是生成Android设备上两个进程之间通讯的代码。
三、Demo例子
我们需要创建两个应用,代表两个进程。
1、服务端写一个IAidl.aidl文件,
package com.txfy.aidl; interface IAidl{ void testAidl(); }2、创建远程服务
public class AidlAService extends Service { private static final String TAG = "AIDLService"; private void Log(String str) { Log.i(TAG, "----------" + str + "----------"); } public void onCreate() { Log("service created"); } public void onStart(Intent intent, int startId) { Log("service started id = " + startId); } //绑定的时候调用的方法 public IBinder onBind(Intent t) { Log("service on bind"); //返回该对象到客户端的onServiceConnected return new MyBinder(); } public void onDestroy() { Log("service on destroy"); super.onDestroy(); } //解绑服务 public boolean onUnbind(Intent intent) { Log("service on unbind"); return super.onUnbind(intent); } public void onRebind(Intent intent) { Log("service on rebind"); super.onRebind(intent); } //创建Binder,返回给客户端的 private class MyBinder extends Stub { //客户端通过代理对象调用testAidl() ,testAidl()再调用服务里面的方法 @Override public void testAidl() throws RemoteException { callMe(); } } public void callMe() { Log("Call service me"); } }
3、AndroidManifest.xml配置,注意Service要放在应用程序唯一包名的文件夹上
<service android:name="com.example.AliPay.AidlAService" > <intent-filter> <action android:name="com.txfy.testAidl" ><!--这个是隐式意图,名字任意起--> </action> </intent-filter> </service>
应用结构如图
4、复制IAidl.aidl文件到客户端,IAidl.aidl所在的包名必须与服务端的包名一致
5、客户端AIDLAActivity.java代码调用远程服务
public class AAIDLActivity extends Activity { private IAidl mItestAidl; private Button mAidlCallbackAidl; private Button mAidlUnbindAidl; private ServiceConnection mConnection; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_aidl); //初始化服务 initService(); initView(); setOnclickListener(); } private void initService() { Intent service = new Intent(); //隐式调用远程服务 // <service android:name="com.example.AliPay.AidlAService" > // <intent-filter> // <action android:name="com.txfy.testAidl" > // </action> // </intent-filter> // </service> service.setAction("com.txfy.testAidl"); mConnection = new MyServiceConnection(); bindService(service, mConnection, Context.BIND_AUTO_CREATE); } private void setOnclickListener() { mAidlCallbackAidl.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { try { //调用远程服务 mItestAidl.testAidl(); } catch (RemoteException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }); mAidlUnbindAidl.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { unbindService(mConnection); } }); } private class MyServiceConnection implements ServiceConnection { @Override public void onServiceConnected(ComponentName name, IBinder service) { // iService = IService.Stub.asInterface(service); // 返回他的代理类 mItestAidl = IAidl.Stub.asInterface(service); } @Override public void onServiceDisconnected(ComponentName name) { } } private void initView() { mAidlCallbackAidl = (Button) findViewById(R.id.id_aidlcallback_btn); mAidlUnbindAidl = (Button) findViewById(R.id.id_aidlunbind_btn); } }
特别注意:如果出现一下错误
**** enforceInterface() expected ‘com.txfy.aidl.IAidl‘ but read ‘com.example.AliPay.IAidl‘
那就是你没把IAidl.aidl放在服务端的唯一包名下面,客户端默认去服务端的唯一包名下面找
enforceInterface() expected 'com.txfy.aidl.IAidl' but read 'com.example.AliPay.IAidl'
标签:android aidl binder enforceinterface
原文地址:http://blog.csdn.net/txfyteen/article/details/44980181