最近从新温习AIDL,发现技术这玩意就跟女人一样,你过久没去了解就会对它陌生却又充满新鲜感,然后查看网上的多半是胡扯,粘贴,我这里整合下,里面如果有错误望大家及时指出。废话不多说,进入主题
首先来了解几点常识:
1,一个Android应用程序对应一个进程;
2,Android应用程序进程间需要借助IPC轻量级通讯协议;
3,切勿把线程和进程的概念搞混乱。一个进程可以包含多个线程,但是一个线程只会附属于一个进程,可以理解成1对多的关系;
4,我们常见的Handler它是运行在UI主线程的,它负责的是异步处理数据,执行也是父线程和子线程;所以别把它和进程的概念混在一起。
进入主题,Android进程间的通讯:AIDL
这里我以为大家比较熟悉的C/S模式来讲解整个通讯过程;但是我并没有去新建立两个项目了,就一个项目中,模拟进程通讯。不多说,先上项目图
第一步,首先建立两个aidl文件,forActivity.adil,forService.aidl 先来看看它们内部实现
- package com.aidl;
- interface forActivity{
- void perAction();
- void showString(int count);
- }
- package com.aidl;
- import com.aidl.forActivity;
- interface forService{
- void registerTestCall(forActivity fa);
- void callBack();
- }
一看,哎哟,这里面的编码规则和java文件一样,但是这个时候,我其他地方要调用怎么办?别着急编译器会默认在gen文件中生成对应.java文件
打开其中一个文件查看下其中源码,先不详细分析,慢慢来,就好比追女生一样,要慢慢来,急不得
- /*
- * This file is auto-generated. DO NOT MODIFY.
- * Original file: F:\\workspace\\AndroidAIDL\\src\\com\\example\\androidaidl\\aidl\\forActivity.aidl
- */
- package com.example.androidaidl.aidl;
- public interface forActivity extends android.os.IInterface
- {
- /** Local-side IPC implementation stub class. */
- public static abstract class Stub extends android.os.Binder implements com.example.androidaidl.aidl.forActivity
- {
- private static final java.lang.String DESCRIPTOR = "com.example.androidaidl.aidl.forActivity";
- /** Construct the stub at attach it to the interface. */
- public Stub()
- {
- this.attachInterface(this, DESCRIPTOR);
- }
- /**
- * Cast an IBinder object into an com.example.androidaidl.aidl.forActivity interface,
- * generating a proxy if needed.
- */
- public static com.example.androidaidl.aidl.forActivity asInterface(android.os.IBinder obj)
- {
- if ((obj==null)) {
- return null;
- }
- android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
- if (((iin!=null)&&(iin instanceof com.example.androidaidl.aidl.forActivity))) {
- return ((com.example.androidaidl.aidl.forActivity)iin);
- }
- return new com.example.androidaidl.aidl.forActivity.Stub.Proxy(obj);
- }
- @Override 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.example.androidaidl.aidl.forActivity
- {
- private android.os.IBinder mRemote;
- Proxy(android.os.IBinder remote)
- {
- mRemote = remote;
- }
- @Override public android.os.IBinder asBinder()
- {
- return mRemote;
- }
- public java.lang.String getInterfaceDescriptor()
- {
- return DESCRIPTOR;
- }
- @Override 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 = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
- }
- public void performAction() throws android.os.RemoteException;
- }
第二步,新建mAIDLActivity.java文件,它模拟Client , 新建mAIDLService.java文件,它模拟Server;
先看看mAIDLActivity.java文件;
- 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) {
- android.util.Log.d(TAG, "------ " + str + "------");
- }
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- // TODO Auto-generated method stub
- super.onCreate(savedInstanceState);
- 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) {
- //绑定服务
- Intent intent = new Intent(mAIDLActivity.this,mAIDLService.class);
- bindService(intent, mcConnection, Context.BIND_AUTO_CREATE);
- //startService(intent);
- }
- });
- btnCancel.setOnClickListener(new OnClickListener() {
- public void onClick(View v) {
- //取消绑定
- unbindService(mcConnection);
- /*unbindService(mConnection);
- // stopService(intent);
- */ }
- });
- btnCallBack.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- try {
- //进程数据交互通讯
- mService.callBack();
- } catch (RemoteException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- });
- }
- forService mService;
- forActivity mActivity = new forActivity.Stub() {
- @Override
- public void perAction() throws RemoteException {
- Log("执行了啦");
- }
- @Override
- public void showString(int count) throws RemoteException {
- Log(count+"");
- }
- };
- ServiceConnection mcConnection = new ServiceConnection() {
- @Override
- public void onServiceDisconnected(ComponentName name) {
- }
- @Override
- public void onServiceConnected(ComponentName name, IBinder service) {
- mService = forService.Stub.asInterface(service);
- try {
- mService.registerTestCall(mActivity);
- } catch (RemoteException e) {
- }
- }
- };
先分析下上述文件
- ServiceConnection mcConnection = new ServiceConnection() {
- @Override
- public void onServiceDisconnected(ComponentName name) {
- }
- @Override
- public void onServiceConnected(ComponentName name, IBinder service) {
- mService = forService.Stub.asInterface(service);
- try {
- mService.registerTestCall(mActivity);
- } catch (RemoteException e) {
- }
- }
- };
看这句代码
- mService = forService.Stub.asInterface(service);
- public interface forService extends android.os.IInterface
- {
- /** Local-side IPC implementation stub class. */
- public static abstract class Stub extends android.os.Binder implements com.aidl.forService
- {
- private static final java.lang.String DESCRIPTOR = "com.aidl.forService";
- /** Construct the stub at attach it to the interface. */
- public Stub()
- {
- this.attachInterface(this, DESCRIPTOR);
- }
- /**
- * Cast an IBinder object into an com.aidl.forService interface,
- * generating a proxy if needed.
- */
- public static com.aidl.forService asInterface(android.os.IBinder obj)
- {
- if ((obj==null)) {
- return null;
- }
- android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
- if (((iin!=null)&&(iin instanceof com.aidl.forService))) {
- return ((com.aidl.forService)iin);
- }
- return new com.aidl.forService.Stub.Proxy(obj);
- }
这里我们发现,Stub是forService的内部静态抽象类,并且是继承Binder和实例化了接口forService. 查看方法adInterface中的实现,它分三步来判断
1,如果是空,直接给你空,让你一边玩去
2,如果传入的Ibinder对象就是com.aidl.forService,因为forService的继承的IInterface,看IInterface的介绍Base class for Binder interfaces. When defining a new interface, you must derive it from IInterface.那得列直接强转成forService对象返回去,万事大吉;
3.如果为空,那就new一个新的,对象嘛.程序猿从来不缺.
下面继续分析mAIDLService文件.不多说,先看源码
- public class mAIDLService extends Service {
- @Override
- public IBinder onBind(Intent intent) {
- return mIBinder;
- }
- forActivity mActivity;
- int count=0;
- forService.Stub mIBinder = new forService.Stub() {
- @Override
- public void registerTestCall(forActivity fa) throws RemoteException {
- mActivity = fa;
- }
- @Override
- public void callBack() throws RemoteException {
- mActivity.perAction();
- mActivity.showString(++count);
- }
- };
- }
它这里相对就简单了,基本不用多说了吧,这里要注意的就是
- public IBinder onBind(Intent intent) {
- return mIBinder;
- }
那这里就慢慢明朗了,整个相互间的通讯也就清楚了,当按下btnCallBack按钮的时候,首先会调用forService中的callBack方法,而callBack方法的实现中又调用了forActivity的perAction.通过forActivity和forService的这次握手,就达到了mAIDLActivity和mAIDLService一直及时通讯
说到这里有朋友跟我说ContentProvider就可以直接实现两个应用间的数据传递了啊,为什么还要用AIDL,我转头一声呵呵,我列出下面几个区分点估计大家就明白了
1.ContentProvider是单向性的,不及时的,而AIDL是双向性,及时的。就这么来说吧。ContentProvider就好比你看到一个漂亮的妹子,你一直看着她,但是她却对你无视,你看不清楚她身体的变化;AIDL就是你看到那个漂亮的妹子,她也看着,你下面的异样,立即反馈给了她,而你也看到了她嘴边的异样,这比喻好理解吗?哈哈哈
好了中间有些地方如果有错或者大家要补充的直接留言吧,然后恳请转载的指明地址,不然又是一堆废文到处跑。
下篇博文准备分析下IBinder和Binder!
参考网友论文
http://blog.youkuaiyun.com/saintswordsman/article/details/5130947
源码下载
http://download.youkuaiyun.com/detail/eran12101030/7993485
原文地址:http://blog.youkuaiyun.com/eran12101030/article/details/39672189