首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 网络技术 > 网络基础 >

android进程间通信:施用AIDL

2012-09-09 
android进程间通信:使用AIDL开发环境为Eclipse。拣重要的先说,来看看aidl文件的内容:文件:forActivity.aidl

android进程间通信:使用AIDL

开发环境为Eclipse。

拣重要的先说,来看看aidl文件的内容:

文件:forActivity.aidl

view plaincopy to clipboardprint?
    package?com.styleflying.AIDL;??interface?ITaskCallback?{??????void?performAction();???

package com.styleflying.AIDL;interface ITaskCallback {void performAction();?

文件:forService.aidl

view plaincopy to clipboardprint?
    package?com.styleflying.AIDL;??import?com.styleflying.AIDL.forActivity;??interface?ITaskBinder?{??????void?registerTestCall(ITaskCallback?tc);??????void?invokCallBack();??}??

package com.styleflying.AIDL;import com.styleflying.AIDL.forActivity;interface ITaskBinder {void registerTestCall(ITaskCallback tc);void invokCallBack();}

这两个文件和Java文件放置的地方一样,看包名。

在Eclipse中它们将被自动编译为forActivity.java和forService.java,它们存放在gen目录下。为了方便手头无法演练的读者,代码贴上,不用细看。

文件forActivity.java:

view plaincopy to clipboardprint?
    /*??*?This?file?is?auto-generated.??DO?NOT?MODIFY.??*?Original?file:?D:\\workspace\\AIDLTest\\src\\com\\styleflying\\AIDL\\forActivity.aidl??*/??package?com.styleflying.AIDL;??import?java.lang.String;??import?android.os.RemoteException;??import?android.os.IBinder;??import?android.os.IInterface;??import?android.os.Binder;??import?android.os.Parcel;??public?interface?forActivity?extends?android.os.IInterface??{??/**?Local-side?IPC?implementation?stub?class.?*/??public?static?abstract?class?Stub?extends?android.os.Binder?implements?com.styleflying.AIDL.forActivity??{??private?static?final?java.lang.String?DESCRIPTOR?=?"com.styleflying.AIDL.forActivity";??/**?Construct?the?stub?at?attach?it?to?the?interface.?*/??public?Stub()??{??this.attachInterface(this,?DESCRIPTOR);??}??/**??*?Cast?an?IBinder?object?into?an?forActivity?interface,??*?generating?a?proxy?if?needed.??*/??public?static?com.styleflying.AIDL.forActivity?asInterface(android.os.IBinder?obj)??{??if?((obj==null))?{??return?null;??}??android.os.IInterface?iin?=?(android.os.IInterface)obj.queryLocalInterface(DESCRIPTOR);??if?(((iin!=null)&&(iin?instanceof?com.styleflying.AIDL.forActivity)))?{??return?((com.styleflying.AIDL.forActivity)iin);??}??return?new?com.styleflying.AIDL.forActivity.Stub.Proxy(obj);??}??public?android.os.IBinder?asBinder()??{??return?this;??}??@Override?public?boolean?onTransact(int?code,?android.os.Parcel?data,?android.os.Parcel?reply,?int?flags)?throws?android.os.RemoteException??{??switch?(code)??{??case?INTERFACE_TRANSACTION:??{??reply.writeString(DESCRIPTOR);??return?true;??}??case?TRANSACTION_performAction:??{??data.enforceInterface(DESCRIPTOR);??this.performAction();??reply.writeNoException();??return?true;??}??}??return?super.onTransact(code,?data,?reply,?flags);??}??private?static?class?Proxy?implements?com.styleflying.AIDL.forActivity??{??private?android.os.IBinder?mRemote;??Proxy(android.os.IBinder?remote)??{??mRemote?=?remote;??}??public?android.os.IBinder?asBinder()??{??return?mRemote;??}??public?java.lang.String?getInterfaceDescriptor()??{??return?DESCRIPTOR;??}??public?void?performAction()?throws?android.os.RemoteException??{??android.os.Parcel?_data?=?android.os.Parcel.obtain();??android.os.Parcel?_reply?=?android.os.Parcel.obtain();??try?{??_data.writeInterfaceToken(DESCRIPTOR);??mRemote.transact(Stub.TRANSACTION_performAction,?_data,?_reply,?0);??_reply.readException();??}??finally?{??_reply.recycle();??_data.recycle();??}??}??}??static?final?int?TRANSACTION_performAction?=?(IBinder.FIRST_CALL_TRANSACTION?+?0);??}??public?void?performAction()?throws?android.os.RemoteException;??}??

/** This file is auto-generated. DO NOT MODIFY. * Original file:D:\\workspace\\AIDLTest\\src\\com\\styleflying\\AIDL\\forActivity.aidl*/package com.styleflying.AIDL;import java.lang.String;import android.os.RemoteException;import android.os.IBinder;import android.os.IInterface;import android.os.Binder;import android.os.Parcel;public interface forActivity extends android.os.IInterface{/** Local-side IPC implementation stub class. */public static abstract class Stub extends android.os.Binder implementscom.styleflying.AIDL.forActivity{private static final java.lang.String DESCRIPTOR ="com.styleflying.AIDL.forActivity";/** Construct the stub at attach it to the interface. */public Stub(){this.attachInterface(this, DESCRIPTOR);}/** * Cast an IBinder object into an forActivity interface, *generating a proxy if needed. */public static com.styleflying.AIDL.forActivityasInterface(android.os.IBinder obj){if ((obj==null)) {return null;}android.os.IInterface iin =(android.os.IInterface)obj.queryLocalInterface(DESCRIPTOR);if (((iin!=null)&&(iin instanceofcom.styleflying.AIDL.forActivity))) {return ((com.styleflying.AIDL.forActivity)iin);}return new com.styleflying.AIDL.forActivity.Stub.Proxy(obj);}public android.os.IBinder asBinder(){return this;}@Override public boolean onTransact(int code, android.os.Parcel data,android.os.Parcel reply, int flags) throws android.os.RemoteException{switch (code){case INTERFACE_TRANSACTION:{reply.writeString(DESCRIPTOR);return true;}case TRANSACTION_performAction:{data.enforceInterface(DESCRIPTOR);this.performAction();reply.writeNoException();return true;}}return super.onTransact(code, data, reply, flags);}private static class Proxy implements com.styleflying.AIDL.forActivity{private android.os.IBinder mRemote;Proxy(android.os.IBinder remote){mRemote = remote;}public android.os.IBinder asBinder(){return mRemote;}public java.lang.String getInterfaceDescriptor(){return DESCRIPTOR;}public void performAction() throws android.os.RemoteException{android.os.Parcel _data = android.os.Parcel.obtain();android.os.Parcel _reply = android.os.Parcel.obtain();try {_data.writeInterfaceToken(DESCRIPTOR);mRemote.transact(Stub.TRANSACTION_performAction, _data, _reply, 0);_reply.readException();}finally {_reply.recycle();_data.recycle();}}}static final int TRANSACTION_performAction =(IBinder.FIRST_CALL_TRANSACTION + 0);}public void performAction() throws android.os.RemoteException;}

文件forService.java:

+ expand sourceview plaincopy to clipboardprint?·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150
    /*??*?This?file?is?auto-generated.??DO?NOT?MODIFY.??*?Original?file:?D:\\workspace\\AIDLTest\\src\\com\\styleflying\\AIDL\\forService.aidl??*/??package?com.styleflying.AIDL;??import?java.lang.String;??import?android.os.RemoteException;??import?android.os.IBinder;??import?android.os.IInterface;??import?android.os.Binder;??import?android.os.Parcel;??public?interface?forService?extends?android.os.IInterface??{??/**?Local-side?IPC?implementation?stub?class.?*/??public?static?abstract?class?Stub?extends?android.os.Binder?implements?com.styleflying.AIDL.forService??{??private?static?final?java.lang.String?DESCRIPTOR?=?"com.styleflying.AIDL.forService";??/**?Construct?the?stub?at?attach?it?to?the?interface.?*/??public?Stub()??{??this.attachInterface(this,?DESCRIPTOR);??}??/**??*?Cast?an?IBinder?object?into?an?forService?interface,??*?generating?a?proxy?if?needed.??*/??public?static?com.styleflying.AIDL.forService?asInterface(android.os.IBinder?obj)??{??if?((obj==null))?{??return?null;??}??android.os.IInterface?iin?=?(android.os.IInterface)obj.queryLocalInterface(DESCRIPTOR);??if?(((iin!=null)&&(iin?instanceof?com.styleflying.AIDL.forService)))?{??return?((com.styleflying.AIDL.forService)iin);??}??return?new?com.styleflying.AIDL.forService.Stub.Proxy(obj);??}??public?android.os.IBinder?asBinder()??{??return?this;??}??@Override?public?boolean?onTransact(int?code,?android.os.Parcel?data,?android.os.Parcel?reply,?int?flags)?throws?android.os.RemoteException??{??switch?(code)??{??case?INTERFACE_TRANSACTION:??{??reply.writeString(DESCRIPTOR);??return?true;??}??case?TRANSACTION_registerTestCall:??{??data.enforceInterface(DESCRIPTOR);??com.styleflying.AIDL.forActivity?_arg0;??_arg0?=?com.styleflying.AIDL.forActivity.Stub.asInterface(data.readStrongBinder());??this.registerTestCall(_arg0);??reply.writeNoException();??return?true;??}??case?TRANSACTION_invokCallBack:??{??data.enforceInterface(DESCRIPTOR);??this.invokCallBack();??reply.writeNoException();??return?true;??}??}??return?super.onTransact(code,?data,?reply,?flags);??}??private?static?class?Proxy?implements?com.styleflying.AIDL.forService??{??private?android.os.IBinder?mRemote;??Proxy(android.os.IBinder?remote)??{??mRemote?=?remote;??}??public?android.os.IBinder?asBinder()??{??return?mRemote;??}??public?java.lang.String?getInterfaceDescriptor()??{??return?DESCRIPTOR;??}??public?void?registerTestCall(com.styleflying.AIDL.forActivity?cb)?throws?android.os.RemoteException??{??android.os.Parcel?_data?=?android.os.Parcel.obtain();??android.os.Parcel?_reply?=?android.os.Parcel.obtain();??try?{??_data.writeInterfaceToken(DESCRIPTOR);??_data.writeStrongBinder((((cb!=null))?(cb.asBinder()):(null)));??mRemote.transact(Stub.TRANSACTION_registerTestCall,?_data,?_reply,?0);??_reply.readException();??}??finally?{??_reply.recycle();??_data.recycle();??}??}??public?void?invokCallBack()?throws?android.os.RemoteException??{??android.os.Parcel?_data?=?android.os.Parcel.obtain();??android.os.Parcel?_reply?=?android.os.Parcel.obtain();??try?{??_data.writeInterfaceToken(DESCRIPTOR);??mRemote.transact(Stub.TRANSACTION_invokCallBack,?_data,?_reply,?0);??_reply.readException();??}??finally?{??_reply.recycle();??_data.recycle();??}??}??}??static?final?int?TRANSACTION_registerTestCall?=?(IBinder.FIRST_CALL_TRANSACTION?+?0);??static?final?int?TRANSACTION_invokCallBack?=?(IBinder.FIRST_CALL_TRANSACTION?+?1);??}??public?void?registerTestCall(com.styleflying.AIDL.forActivity?cb)?throws?android.os.RemoteException;??public?void?invokCallBack()?throws?android.os.RemoteException;??}??

/** This file is auto-generated. DO NOT MODIFY. * Original file:D:\\workspace\\AIDLTest\\src\\com\\styleflying\\AIDL\\forService.aidl*/package com.styleflying.AIDL;import java.lang.String;import android.os.RemoteException;import android.os.IBinder;import android.os.IInterface;import android.os.Binder;import android.os.Parcel;public interface forService extends android.os.IInterface{/** Local-side IPC implementation stub class. */public static abstract class Stub extends android.os.Binder implementscom.styleflying.AIDL.forService{private static final java.lang.String DESCRIPTOR ="com.styleflying.AIDL.forService";/** Construct the stub at attach it to the interface. */public Stub(){this.attachInterface(this, DESCRIPTOR);}/** * Cast an IBinder object into an forService interface, * generatinga proxy if needed. */public static com.styleflying.AIDL.forServiceasInterface(android.os.IBinder obj){if ((obj==null)) {return null;}android.os.IInterface iin =(android.os.IInterface)obj.queryLocalInterface(DESCRIPTOR);if (((iin!=null)&&(iin instanceofcom.styleflying.AIDL.forService))) {return ((com.styleflying.AIDL.forService)iin);}return new com.styleflying.AIDL.forService.Stub.Proxy(obj);}public android.os.IBinder asBinder(){return this;}@Override public boolean onTransact(int code, android.os.Parcel data,android.os.Parcel reply, int flags) throws android.os.RemoteException{switch (code){case INTERFACE_TRANSACTION:{reply.writeString(DESCRIPTOR);return true;}case TRANSACTION_registerTestCall:{data.enforceInterface(DESCRIPTOR);com.styleflying.AIDL.forActivity _arg0;_arg0 =com.styleflying.AIDL.forActivity.Stub.asInterface(data.readStrongBinder());this.registerTestCall(_arg0);reply.writeNoException();returntrue;}case TRANSACTION_invokCallBack:{data.enforceInterface(DESCRIPTOR);this.invokCallBack();reply.writeNoException();return true;}}return super.onTransact(code, data, reply, flags);}private static class Proxy implements com.styleflying.AIDL.forService{private android.os.IBinder mRemote;Proxy(android.os.IBinder remote){mRemote = remote;}public android.os.IBinder asBinder(){return mRemote;}public java.lang.String getInterfaceDescriptor(){return DESCRIPTOR;}public void registerTestCall(com.styleflying.AIDL.forActivity cb)throws android.os.RemoteException{android.os.Parcel _data = android.os.Parcel.obtain();android.os.Parcel _reply = android.os.Parcel.obtain();try {_data.writeInterfaceToken(DESCRIPTOR);_data.writeStrongBinder((((cb!=null))?(cb.asBinder()):(null)));mRemote.transact(Stub.TRANSACTION_registerTestCall, _data, _reply, 0);_reply.readException();}finally {_reply.recycle();_data.recycle();}}public void invokCallBack() throws android.os.RemoteException{android.os.Parcel _data = android.os.Parcel.obtain();android.os.Parcel _reply = android.os.Parcel.obtain();try {_data.writeInterfaceToken(DESCRIPTOR);mRemote.transact(Stub.TRANSACTION_invokCallBack, _data, _reply, 0);_reply.readException();}finally {_reply.recycle();_data.recycle();}}}static final int TRANSACTION_registerTestCall =(IBinder.FIRST_CALL_TRANSACTION + 0);static final int TRANSACTION_invokCallBack =(IBinder.FIRST_CALL_TRANSACTION + 1);}public void registerTestCall(com.styleflying.AIDL.forActivity cb)throws android.os.RemoteException;public void invokCallBack() throws android.os.RemoteException;}

两段代码差不多,前面基本一样,从后面看,最后跟着我们在AIDL中自定义的方法,没有实现。两个文件各定义一个了接口,这两个接口分别会在Activity和Service中使用,在那里我们将实现自定义的方法。两个接口中都定义了一个抽象类Stub,实现所在的接口。Stub中又有一个类Proxy。Stub中有一个static的asInterface()方法,里面有很多return语句,在mAIDLActivity中调用它时,它返回一个新创建的内部类Proxy对象。

这个Stub对我们来说很有用,它继承了Binder。Binder有什么用呢?一个类,继承了Binder,那么它的对象就可以被远程的进程使用了(前提是远程进程获取了这个类的对象【对象的引用】,至于如如何获得看下文),在本例中就是说,如果一个Service中有一个继承了Stub的类的对象,那么这个对象中的方法就可以在Activity中使用,对Activity也是这样。至于Binder的细节,网上有很多贴介绍,看不明白也不影响我们完成这个例子。

再看mAIDLActivity.java:

view plaincopy to clipboardprint?
    package?com.styleflying.AIDL;??import?android.app.Activity;??import?android.content.ComponentName;??import?android.content.Context;??import?android.content.Intent;??import?android.content.ServiceConnection;??import?android.os.Bundle;??import?android.os.IBinder;??import?android.os.RemoteException;??import?android.util.Log;??import?android.view.View;??import?android.view.View.OnClickListener;??import?android.widget.Button;??import?android.widget.Toast;??public?class?mAIDLActivity?extends?Activity?{??????private?static?final?String?TAG?=?"AIDLActivity";??????private?Button?btnOk;??????private?Button?btnCancel;??????private?Button?btnCallBack;????????????private?void?Log(String?str)?{??????????Log.d(TAG,?"------?"?+?str?+?"------");??????????}????????????private?forActivity?mCallback?=?new?forActivity.Stub()?{??????????public?void?performAction()?throws?RemoteException??????????{??????????????Toast.makeText(mAIDLActivity.this,?"this?toast?is?called?from?service",?1).show();??????????}??????????};????????????????forService?mService;??????private?ServiceConnection?mConnection?=?new?ServiceConnection()?{??????????public?void?onServiceConnected(ComponentName?className,??????????????????IBinder?service)?{??????????????mService?=?forService.Stub.asInterface(service);??????????????try?{??????????????????mService.registerTestCall(mCallback);}??????????????catch?(RemoteException?e)?{????????????????????????????????}??????????????}??????????public?void?onServiceDisconnected(ComponentName?className)?{??????????????Log("disconnect?service");??????????????mService?=?null;??????????????}??????????};??????@Override??????public?void?onCreate(Bundle?icicle)?{??????????super.onCreate(icicle);??????????setContentView(R.layout.main);??????????btnOk?=?(Button)findViewById(R.id.btn_ok);??????????btnCancel?=?(Button)findViewById(R.id.btn_cancel);??????????btnCallBack?=?(Button)findViewById(R.id.btn_callback);??????????btnOk.setOnClickListener(new?OnClickListener()?{??????????????public?void?onClick(View?v)?{??????????????????Bundle?args?=?new?Bundle();??????????????????Intent?intent?=?new?Intent(mAIDLActivity.this,?mAIDLService.class);??????????????????intent.putExtras(args);??????????????????bindService(intent,?mConnection,?Context.BIND_AUTO_CREATE);??????????????????startService(intent);??????????????????}??????????????});??????????btnCancel.setOnClickListener(new?OnClickListener()?{??????????????public?void?onClick(View?v)?{??????????????????unbindService(mConnection);??????????????????//stopService(intent);??????????????????}??????????????});??????????btnCallBack.setOnClickListener(new?OnClickListener()?{????????????????????????????@Override??????????????public?void?onClick(View?v)??????????????{??????????????????try??????????????????{??????????????????????mService.invokCallBack();??????????????????}?catch?(RemoteException?e)??????????????????{??????????????????????//?TODO?Auto-generated?catch?block??????????????????????e.printStackTrace();??????????????????}??????????????}??????????});??????????}??}??

package com.styleflying.AIDL;import android.app.Activity;import android.content.ComponentName;import android.content.Context;import android.content.Intent;import android.content.ServiceConnection;import android.os.Bundle;import android.os.IBinder;import android.os.RemoteException;import android.util.Log;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.Toast;public class mAIDLActivity extends Activity {private static final String TAG = "AIDLActivity";private Button btnOk; private Button btnCancel; private Button btnCallBack; private void Log(String str) { Log.d(TAG, "------ " + str + "------"); } private forActivity mCallback = new forActivity.Stub() {public void performAction() throws RemoteException{Toast.makeText(mAIDLActivity.this, "this toast is called from service", 1).show();}};forService mService;private ServiceConnection mConnection = new ServiceConnection() {public void onServiceConnected(ComponentName className,IBinder service) {mService = forService.Stub.asInterface(service);try {mService.registerTestCall(mCallback);}catch (RemoteException e) {}}public void onServiceDisconnected(ComponentName className) {Log("disconnect service");mService = null;}}; @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); setContentView(R.layout.main); btnOk = (Button)findViewById(R.id.btn_ok); btnCancel = (Button)findViewById(R.id.btn_cancel); btnCallBack = (Button)findViewById(R.id.btn_callback); btnOk.setOnClickListener(new OnClickListener() { public void onClick(View v) { Bundle args = new Bundle(); Intent intent = new Intent(mAIDLActivity.this, mAIDLService.class); intent.putExtras(args); bindService(intent, mConnection, Context.BIND_AUTO_CREATE); startService(intent); } }); btnCancel.setOnClickListener(new OnClickListener() { public void onClick(View v) { unbindService(mConnection); //stopService(intent); } }); btnCallBack.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v){try{mService.invokCallBack();} catch (RemoteException e){// TODO Auto-generated catch blocke.printStackTrace();}}}); }}

很短,相信大家很容易看明白。注意mConnection,它的onServiceConnected()中有一句mService =forService.Stub.asInterface(service);给mService赋值了,这个mService是一个forService,而service是onServiceConnected()传进来的参数,onServiceConnected()会在连接Service的时候被系统调用,这个service参数的值来自哪里呢?看mAIDLService.java:

view plaincopy to clipboardprint?
    package?com.styleflying.AIDL;??import?android.app.Service;??import?android.content.Intent;??import?android.os.IBinder;??import?android.os.RemoteCallbackList;??import?android.os.RemoteException;??import?android.util.Log;??public?class?mAIDLService?extends?Service?{??????private?static?final?String?TAG?=?"AIDLService";????????private?forActivity?callback;??????private?void?Log(String?str)?{??????????Log.d(TAG,?"------?"?+?str?+?"------");??????}??????@Override??????public?void?onCreate()?{??????????Log("service?create");??????}??????@Override??????public?void?onStart(Intent?intent,?int?startId)?{??????????Log("service?start?id="?+?startId);??????}????????????@Override??????public?IBinder?onBind(Intent?t)?{??????????Log("service?on?bind");??????????return?mBinder;??????}??????@Override??????public?void?onDestroy()?{??????????Log("service?on?destroy");??????????super.onDestroy();??????}??????@Override??????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);??????}??????private?final?forService.Stub?mBinder?=?new?forService.Stub()?{??????????@Override??????????public?void?invokCallBack()?throws?RemoteException??????????{??????????????callback.performAction();????????????????????????}??????????@Override??????????public?void?registerTestCall(forActivity?cb)?throws?RemoteException??????????{??????????????callback?=?cb;????????????????????????}????????????????};??}??

package com.styleflying.AIDL;import android.app.Service;import android.content.Intent;import android.os.IBinder;import android.os.RemoteCallbackList;import android.os.RemoteException;import android.util.Log;public class mAIDLService extends Service { private static final String TAG = "AIDLService"; private forActivity callback; private void Log(String str) { Log.d(TAG, "------ " + str + "------"); } @Override public void onCreate() { Log("service create"); } @Override public void onStart(Intent intent, int startId) { Log("service start id=" + startId); } @Override public IBinder onBind(Intent t) { Log("service on bind"); return mBinder; } @Override public void onDestroy() { Log("service on destroy"); super.onDestroy(); } @Override 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); } private final forService.Stub mBinder = new forService.Stub() {@Overridepublic void invokCallBack() throws RemoteException{callback.performAction();}@Overridepublic void registerTestCall(forActivity cb) throws RemoteException{callback = cb;} };}

注意onBind(),它的返回类型为IBinder,返回了一个mBinder,看看mBinder的定义:

??? private final forService.Stub mBinder = new forService.Stub() {

??????? @Override
??? ??? public void invokCallBack() throws RemoteException
??? ??? {
??? ??? ??? callback.performAction();
??? ???? }

??????? @Override
??? ??? public void registerTestCall(forActivity cb) throws RemoteException
??? ??? {
??? ??? ??? callback = cb;

??????? }

?????? };

它是实现了我们在AIDL中定义的方法,这个mBinder最终返回给了mAIDLActivity中的mService,于是在mAIDLActivity中可以使用mBinder中的方法了。在mAIDLActivity中也有一个类似mBinder的对象,看看定义: ??

??????? private forActivity mCallback = new forActivity.Stub()

??? {
?? ??? ?public void performAction() throws RemoteException
?? ??? ?{
?? ??? ??? ?Toast.makeText(mAIDLActivity.this, "this toast is called from service", 1).show();
?? ??? ?}
?? ?? };

我们要在界面上显示一个toast,就是在这里实现的。这个对象,在mConnection的onServiceConnected()被调用时,通过调用mService(也就是远程的mAIDLService中的mBinder)的registerTestCall(),传递给了mAIDLService,于是在mAIDLService中可以调用performAction()了。

很啰嗦,只为了能把这个细节说清楚。请大家认真看,我尽量避免错别字、混乱的大小写和逻辑不清的语法,相信你会看明白。是不是很简单?再啰嗦一下,做一个大致总结,我们使用AIDL是要做什么呢:

让Acticity(或者说一个进程/一个类?)和Service(或者说远端进程/远端类/对象?)获取对方的一个Stub对象,这个对象在定义时实现了我们在AIDL中定义的方法,于是这些远程对象中的方法可以在本地使用了。如果这种使用(通信)是单向的,比如只是Activity需要通知Service做什么,那么只要Service中有一个Stub对象,并且传给Acticity就够了。

至于如何获得远程的Stub,参看上面的代码,看mConnection、registerTestCall、onRebind,它们展示了一种方法。

另外,有时候我们可能在一个类中有多个Stub对象,它们都要给远程交互的类的实例,这个时候可以考虑使用RemoteCallbackList<>(docs/reference/android/os/RemoteCallbackList.html)。

欢迎阅读、收藏本文。例子随手写的,功能只在演示AIDL的使用。您可以转载本文,但请勿盲目乱贴。不是我小气,我不权威,我怕它被贴到泛滥,以讹传讹,害了人。

热点排行