android 多进程 Binder AIDL Service

本文參考http://blog.csdn.net/saintswordsman/article/details/5130947
android的多进程是通过Binder来实现的,一个类,继承了Binder,那么它的对象就能够被远程的进程使用了(前提是远程进程获取了这个类的对象【对象的引用】,至于如怎样获得看下文),怎么使用呢?在Android中, 则採用AIDL(Android InterfaceDefinition Language:接口定义语言)方式实现。所以我们必须写后缀为.aidl的文件。.aidl文件放在src以下,刷新一下就会生成同名的.java文件


文件:forActivity.aidl

[java] view plaincopy
  1. package com.styleflying.AIDL;  
  2. interface forActivity {  
  3.     void performAction();  
  4.     }  
 

文件:forService.aidl

[java] view plaincopy
  1. package com.styleflying.AIDL;  
  2. import com.styleflying.AIDL.forActivity;  
  3. interface forService {  
  4.     void registerTestCall(forActivity cb);  
  5.     void invokCallBack();  
  6. }  


 
这两个文件和Java文件放置的地方一样,看包名。
在Eclipse中它们将被自己主动编译为forActivity.java和forService.java。它们存放在gen文件夹下。

为了方便手头无法演练的读者。代码贴上,不用细看。

文件forActivity.java:

[java] view plaincopy
  1. /* 
  2.  * This file is auto-generated.  DO NOT MODIFY. 
  3.  * Original file: D://workspace//AIDLTest//src//com//styleflying//AIDL//forActivity.aidl 
  4.  */  
  5. package com.styleflying.AIDL;  
  6. import java.lang.String;  
  7. import android.os.RemoteException;  
  8. import android.os.IBinder;  
  9. import android.os.IInterface;  
  10. import android.os.Binder;  
  11. import android.os.Parcel;  
  12. public interface forActivity extends android.os.IInterface  
  13. {  
  14. /** Local-side IPC implementation stub class. */  
  15. public static abstract class Stub extends android.os.Binder implements com.styleflying.AIDL.forActivity  
  16. {  
  17. private static final java.lang.String DESCRIPTOR = "com.styleflying.AIDL.forActivity";  
  18. /** Construct the stub at attach it to the interface. */  
  19. public Stub()  
  20. {  
  21. this.attachInterface(this, DESCRIPTOR);  
  22. }  
  23. /** 
  24.  * Cast an IBinder object into an forActivity interface, 
  25.  * generating a proxy if needed. 
  26.  */  
  27. public static com.styleflying.AIDL.forActivity asInterface(android.os.IBinder obj)  
  28. {  
  29. if ((obj==null)) {  
  30. return null;  
  31. }  
  32. android.os.IInterface iin = (android.os.IInterface)obj.queryLocalInterface(DESCRIPTOR);  
  33. if (((iin!=null)&&(iin instanceof com.styleflying.AIDL.forActivity))) {  
  34. return ((com.styleflying.AIDL.forActivity)iin);  
  35. }  
  36. return new com.styleflying.AIDL.forActivity.Stub.Proxy(obj);  
  37. }  
  38. public android.os.IBinder asBinder()  
  39. {  
  40. return this;  
  41. }  
  42. @Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException  
  43. {  
  44. switch (code)  
  45. {  
  46. case INTERFACE_TRANSACTION:  
  47. {  
  48. reply.writeString(DESCRIPTOR);  
  49. return true;  
  50. }  
  51. case TRANSACTION_performAction:  
  52. {  
  53. data.enforceInterface(DESCRIPTOR);  
  54. this.performAction();  
  55. reply.writeNoException();  
  56. return true;  
  57. }  
  58. }  
  59. return super.onTransact(code, data, reply, flags);  
  60. }  
  61. private static class Proxy implements com.styleflying.AIDL.forActivity  
  62. {  
  63. private android.os.IBinder mRemote;  
  64. Proxy(android.os.IBinder remote)  
  65. {  
  66. mRemote = remote;  
  67. }  
  68. public android.os.IBinder asBinder()  
  69. {  
  70. return mRemote;  
  71. }  
  72. public java.lang.String getInterfaceDescriptor()  
  73. {  
  74. return DESCRIPTOR;  
  75. }  
  76. public void performAction() throws android.os.RemoteException  
  77. {  
  78. android.os.Parcel _data = android.os.Parcel.obtain();  
  79. android.os.Parcel _reply = android.os.Parcel.obtain();  
  80. try {  
  81. _data.writeInterfaceToken(DESCRIPTOR);  
  82. mRemote.transact(Stub.TRANSACTION_performAction, _data, _reply, 0);  
  83. _reply.readException();  
  84. }  
  85. finally {  
  86. _reply.recycle();  
  87. _data.recycle();  
  88. }  
  89. }  
  90. }  
  91. static final int TRANSACTION_performAction = (IBinder.FIRST_CALL_TRANSACTION + 0);  
  92. }  
  93. public void performAction() throws android.os.RemoteException;  
  94. }  

文件forService.java:

[java] view plaincopy
  1. /* 
  2.  * This file is auto-generated.  DO NOT MODIFY. 
  3.  * Original file: D://workspace//AIDLTest//src//com//styleflying//AIDL//forService.aidl 
  4.  */  
  5. package com.styleflying.AIDL;  
  6. import java.lang.String;  
  7. import android.os.RemoteException;  
  8. import android.os.IBinder;  
  9. import android.os.IInterface;  
  10. import android.os.Binder;  
  11. import android.os.Parcel;  
  12. public interface forService extends android.os.IInterface  
  13. {  
  14. /** Local-side IPC implementation stub class. */  
  15. public static abstract class Stub extends android.os.Binder implements com.styleflying.AIDL.forService  
  16. {  
  17. private static final java.lang.String DESCRIPTOR = "com.styleflying.AIDL.forService";  
  18. /** Construct the stub at attach it to the interface. */  
  19. public Stub()  
  20. {  
  21. this.attachInterface(this, DESCRIPTOR);  
  22. }  
  23. /** 
  24.  * Cast an IBinder object into an forService interface, 
  25.  * generating a proxy if needed. 
  26.  */  
  27. public static com.styleflying.AIDL.forService asInterface(android.os.IBinder obj)  
  28. {  
  29. if ((obj==null)) {  
  30. return null;  
  31. }  
  32. android.os.IInterface iin = (android.os.IInterface)obj.queryLocalInterface(DESCRIPTOR);  
  33. if (((iin!=null)&&(iin instanceof com.styleflying.AIDL.forService))) {  
  34. return ((com.styleflying.AIDL.forService)iin);  
  35. }  
  36. return new com.styleflying.AIDL.forService.Stub.Proxy(obj);  
  37. }  
  38. public android.os.IBinder asBinder()  
  39. {  
  40. return this;  
  41. }  
  42. @Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException  
  43. {  
  44. switch (code)  
  45. {  
  46. case INTERFACE_TRANSACTION:  
  47. {  
  48. reply.writeString(DESCRIPTOR);  
  49. return true;  
  50. }  
  51. case TRANSACTION_registerTestCall:  
  52. {  
  53. data.enforceInterface(DESCRIPTOR);  
  54. com.styleflying.AIDL.forActivity _arg0;  
  55. _arg0 = com.styleflying.AIDL.forActivity.Stub.asInterface(data.readStrongBinder());  
  56. this.registerTestCall(_arg0);  
  57. reply.writeNoException();  
  58. return true;  
  59. }  
  60. case TRANSACTION_invokCallBack:  
  61. {  
  62. data.enforceInterface(DESCRIPTOR);  
  63. this.invokCallBack();  
  64. reply.writeNoException();  
  65. return true;  
  66. }  
  67. }  
  68. return super.onTransact(code, data, reply, flags);  
  69. }  
  70. private static class Proxy implements com.styleflying.AIDL.forService  
  71. {  
  72. private android.os.IBinder mRemote;  
  73. Proxy(android.os.IBinder remote)  
  74. {  
  75. mRemote = remote;  
  76. }  
  77. public android.os.IBinder asBinder()  
  78. {  
  79. return mRemote;  
  80. }  
  81. public java.lang.String getInterfaceDescriptor()  
  82. {  
  83. return DESCRIPTOR;  
  84. }  
  85. public void registerTestCall(com.styleflying.AIDL.forActivity cb) throws android.os.RemoteException  
  86. {  
  87. android.os.Parcel _data = android.os.Parcel.obtain();  
  88. android.os.Parcel _reply = android.os.Parcel.obtain();  
  89. try {  
  90. _data.writeInterfaceToken(DESCRIPTOR);  
  91. _data.writeStrongBinder((((cb!=null))?(cb.asBinder()):(null)));  
  92. mRemote.transact(Stub.TRANSACTION_registerTestCall, _data, _reply, 0);  
  93. _reply.readException();  
  94. }  
  95. finally {  
  96. _reply.recycle();  
  97. _data.recycle();  
  98. }  
  99. }  
  100. public void invokCallBack() throws android.os.RemoteException  
  101. {  
  102. android.os.Parcel _data = android.os.Parcel.obtain();  
  103. android.os.Parcel _reply = android.os.Parcel.obtain();  
  104. try {  
  105. _data.writeInterfaceToken(DESCRIPTOR);  
  106. mRemote.transact(Stub.TRANSACTION_invokCallBack, _data, _reply, 0);  
  107. _reply.readException();  
  108. }  
  109. finally {  
  110. _reply.recycle();  
  111. _data.recycle();  
  112. }  
  113. }  
  114. }  
  115. static final int TRANSACTION_registerTestCall = (IBinder.FIRST_CALL_TRANSACTION + 0);  
  116. static final int TRANSACTION_invokCallBack = (IBinder.FIRST_CALL_TRANSACTION + 1);  
  117. }  
  118. public void registerTestCall(com.styleflying.AIDL.forActivity cb) throws android.os.RemoteException;  
  119. public void invokCallBack() throws android.os.RemoteException;  
  120. }  


我们能够看到在.java文件里都定义了一个抽象类Stub,Stub就是继承Binder。
好了,那我们那里用到了Binder呢?没错,就是Service,Service使用有两种方法,startService。bindeService。bindeService时在实现Service就必须实现 onBind 返回一个Binder对象,这个Binder对象就会被activity回调使用。

这样activity跟service就能够通信了。

当然是activity能够调用service了。

接下来的样例还实现了相互调用。

看mAIDLService.java:

[java] view plaincopy
  1. package com.styleflying.AIDL;  
  2. import android.app.Service;  
  3. import android.content.Intent;  
  4. import android.os.IBinder;  
  5. import android.os.RemoteCallbackList;  
  6. import android.os.RemoteException;  
  7. import android.util.Log;  
  8. public class mAIDLService extends Service {  
  9.     private static final String TAG = "AIDLService";    
  10.     private forActivity callback;  
  11.     private void Log(String str) {  
  12.         Log.d(TAG, "------ " + str + "------");  
  13.     }  
  14.     @Override  
  15.     public void onCreate() {  
  16.         Log("service create");  
  17.     }  
  18.     @Override  
  19.     public void onStart(Intent intent, int startId) {  
  20.         Log("service start id=" + startId);  
  21.     }  
  22.       
  23.     @Override  
  24.     public IBinder onBind(Intent t) {  
  25.         Log("service on bind");  
  26.         return mBinder;  
  27.     }  
  28.     @Override  
  29.     public void onDestroy() {  
  30.         Log("service on destroy");  
  31.         super.onDestroy();  
  32.     }  
  33.     @Override  
  34.     public boolean onUnbind(Intent intent) {  
  35.         Log("service on unbind");  
  36.         return super.onUnbind(intent);  
  37.     }  
  38.     public void onRebind(Intent intent) {  
  39.         Log("service on rebind");  
  40.         super.onRebind(intent);  
  41.     }  
  42.     private final forService.Stub mBinder = new forService.Stub() {  
  43.         @Override  
  44.         public void invokCallBack() throws RemoteException  
  45.         {  
  46.             callback.performAction();  
  47.               
  48.         }  
  49.         @Override  
  50.         public void registerTestCall(forActivity cb) throws RemoteException  
  51.         {  
  52.             callback = cb;  
  53.               
  54.         }  
  55.           
  56.     };  
  57. }  


当中mBinder就是给activity调用了。然而这个类中的mBinder 中的registerTestCall传递的forActivity就是能service调用activity用的。

看mAIDLActivity.java:

[java] view plaincopy
  1. package com.styleflying.AIDL;  
  2. import android.app.Activity;  
  3. import android.content.ComponentName;  
  4. import android.content.Context;  
  5. import android.content.Intent;  
  6. import android.content.ServiceConnection;  
  7. import android.os.Bundle;  
  8. import android.os.IBinder;  
  9. import android.os.RemoteException;  
  10. import android.util.Log;  
  11. import android.view.View;  
  12. import android.view.View.OnClickListener;  
  13. import android.widget.Button;  
  14. import android.widget.Toast;  
  15. public class mAIDLActivity extends Activity {  
  16.     private static final String TAG = "AIDLActivity";  
  17.     private Button btnOk;  
  18.     private Button btnCancel;  
  19.     private Button btnCallBack;  
  20.       
  21.     private void Log(String str) {  
  22.         Log.d(TAG, "------ " + str + "------");  
  23.         }  
  24.       
  25.     private forActivity mCallback = new forActivity.Stub() {  
  26.         public void performAction() throws RemoteException  
  27.         {  
  28.             Toast.makeText(mAIDLActivity.this"this toast is called from service"1).show();  
  29.         }  
  30.         };  
  31.           
  32.     forService mService;  
  33.     private ServiceConnection mConnection = new ServiceConnection() {  
  34.         public void onServiceConnected(ComponentName className,  
  35.                 IBinder service) {  
  36.             mService = forService.Stub.asInterface(service);  
  37.             try {  
  38.                 mService.registerTestCall(mCallback);}  
  39.             catch (RemoteException e) {  
  40.                   
  41.             }  
  42.             }  
  43.         public void onServiceDisconnected(ComponentName className) {  
  44.             Log("disconnect service");  
  45.             mService = null;  
  46.             }  
  47.         };  
  48.     @Override  
  49.     public void onCreate(Bundle icicle) {  
  50.         super.onCreate(icicle);  
  51.         setContentView(R.layout.main);  
  52.         btnOk = (Button)findViewById(R.id.btn_ok);  
  53.         btnCancel = (Button)findViewById(R.id.btn_cancel);  
  54.         btnCallBack = (Button)findViewById(R.id.btn_callback);  
  55.         btnOk.setOnClickListener(new OnClickListener() {  
  56.             public void onClick(View v) {  
  57.                 Bundle args = new Bundle();  
  58.                 Intent intent = new Intent(mAIDLActivity.this, mAIDLService.class);  
  59.                 intent.putExtras(args);  
  60.                 bindService(intent, mConnection, Context.BIND_AUTO_CREATE);  
  61.                 startService(intent);  
  62.                 }  
  63.             });  
  64.         btnCancel.setOnClickListener(new OnClickListener() {  
  65.             public void onClick(View v) {  
  66.                 unbindService(mConnection);  
  67.                 //stopService(intent);  
  68.                 }  
  69.             });  
  70.         btnCallBack.setOnClickListener(new OnClickListener() {  
  71.               
  72.             @Override  
  73.             public void onClick(View v)  
  74.             {  
  75.                 try  
  76.                 {  
  77.                     mService.invokCallBack();  
  78.                 } catch (RemoteException e)  
  79.                 {  
  80.                     // TODO Auto-generated catch block  
  81.                     e.printStackTrace();  
  82.                 }  
  83.             }  
  84.         });  
  85.         }  
  86. }  


当中button点击bindeService时就会触发ServiceConnection,返回了mService = forService.Stub.asInterface(service); activity跟service实现了通信,再mService.registerTestCall(mCallback);} 这样service跟activity又能通信了。在mService.invokCallBack();顺序是activity->service->activity
还有几篇android多进程通信写得不错一并贴出来
http://www.cnblogs.com/BeyondAnyTime/p/3204119.html
http://www.apkbus.com/android-83462-1-1.html
http://blog.csdn.net/baodinglaolang/article/details/9903499
原文地址:https://www.cnblogs.com/yjbjingcha/p/6897743.html