enforceInterface() expected 'com.txfy.aidl.IAidl' but read 'com.example.AliPay.IAidl'

来源:互联网 发布:公交导航软件 编辑:程序博客网 时间:2024/05/17 06:08

一、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");//返回该对象到客户端的onServiceConnectedreturn 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()再调用服务里面的方法@Overridepublic 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;@Overrideprotected 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() {@Overridepublic void onClick(View v) {try {//调用远程服务mItestAidl.testAidl();} catch (RemoteException e) {// TODO Auto-generated catch blocke.printStackTrace();}}});mAidlUnbindAidl.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {unbindService(mConnection);}});}private class MyServiceConnection implements ServiceConnection {@Overridepublic void onServiceConnected(ComponentName name, IBinder service) {// iService = IService.Stub.asInterface(service);// 返回他的代理类mItestAidl = IAidl.Stub.asInterface(service);}@Overridepublic 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放在服务端的唯一包名下面,客户端默认去服务端的唯一包名下面找



0 0