zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    unity c# 获取系统时间
    如果你想让继承MonoBehaviour的类变成Singleten
    关于程序员
    开始养成记录的习惯吧
    关于结构体的赋值问题
    数学中的集合,群,环,域
    励志
    [编程题] 进制均值
    javaEE 入门
    jsp内置对象2
  • 原文地址:https://www.cnblogs.com/yjbjingcha/p/6897743.html
Copyright © 2011-2022 走看看