现在的位置: 首页 > 综合 > 正文

AIDL的一点理解 AIDL的一点理解

2017年12月12日 ⁄ 综合 ⁄ 共 7959字 ⁄ 字号 评论关闭

AIDL的一点理解

分类: Android 68人阅读 评论(0) 收藏 举报

最近参与了一个项目,其中有用到两个APK间进行通信,最终采用的是AIDL,于是自己小研究了下,如有错误,请大家指正。

1.  创建.aidl文件

首先,创建.aidl文件。这个文件类似于声明文件,对于服务器端而言,就是声明你需要对外提供什么接口;对于客户端来说,声明了自己将要用到的接口。所以,不仅服务器端要创建.aidl文件,客户端同样需要。而且是客户端的.aidl文件要和服务器端的一样。所以服务器端一旦公布了对外接口,最好就不要改啦,因为会有很多客户端将用。

下面这两个文件IEmilyService.aidl 是EmilyService.apk 里的定义的,IEmilyServiceCallBack.aidl 这个是EmilySecondClient.apk定义的,因为这个两个apk需要进行双向通信。

但是在两个apk中,这个两个文件是必须都具备的。说白了就是为了方便互相调接口...

IEmilyService.aidl

  1. package com.example.fwk;  
  2. import com.example.fwk.IEmilyServiceCallBack;  
  3.   
  4. interface IEmilyService {  
  5.   
  6.     void registerCallback(IEmilyServiceCallBack cb);  
  7.   
  8.     void unregisterCallback(IEmilyServiceCallBack cb);  
  9.   
  10.     void serviceShow();  
  11. }  

IEmilyServiceCallBack.aidl

  1. package com.example.fwk;  
  2.   
  3. interface IEmilyServiceCallBack {  
  4.   
  5.     void serviceCallBackShow();  
  6.   
  7. }  

2. 实现接口并将接口暴露给客户端

这个两个文件在编译后会自动生成.java文件。额,因为我用的是eclipse, 一运行就自己生成了,也没仔细看里面具体都有啥。从文档里得知,里面东西还是很重要的。尤其是一个内部类Stub,它是父类接口的抽象实现,里面定义了.aidl中的所有方法。

mBinder是IEmilyService.Stub的对象,里面实现了IEmilyService.aidl里定义的所有方法。当有客户端连接的时候,也就是来onBind(), 客户端会得到mBinder这个实例。

EmilyService

  1. package com.example.emilyservice;  
  2.   
  3. import com.example.fwk.IEmilyService;  
  4. import com.example.fwk.IEmilyServiceCallBack;  
  5.   
  6. import android.os.IBinder;  
  7. import android.os.RemoteCallbackList;  
  8. import android.os.RemoteException;  
  9. import android.app.Service;  
  10. import android.content.Intent;  
  11. import android.util.Log;  
  12.   
  13. public class EmilyService extends Service {  
  14.     private static final String TAG = "EmilyService";  
  15.   
  16.     /* 
  17.      * This is a list of callbacks that have been registered with the 
  18.      * service. 
  19.      */  
  20.     final RemoteCallbackList<IEmilyServiceCallBack> mCallbacks =  
  21.             new RemoteCallbackList<IEmilyServiceCallBack>();  
  22.   
  23.     /* 
  24.      * Implements the interface. 
  25.      * 1. The mBinder is an instance of the Stub class (a Binder), which defines the RPC interface for the service. 
  26.      * 2. This instance will be exposed to clients, so the clients can interact with the service. 
  27.      * 3. If one service takes too much time to complete a request, you should avoid to call it from the main thread, 
  28.      * you should call it from a separate thread in the client, in this way to avoid ANR. 
  29.      */  
  30.     private final IEmilyService.Stub mBinder = new IEmilyService.Stub() {  
  31.         public void registerCallback(IEmilyServiceCallBack cb) {  
  32.             Log.i(TAG, "___________registerCallback()");  
  33.             if (cb != null) mCallbacks.register(cb);  
  34.         }  
  35.   
  36.         public void unregisterCallback(IEmilyServiceCallBack cb) {  
  37.             Log.i(TAG, "___________unregisterCallback()");  
  38.             if (cb != null) mCallbacks.unregister(cb);  
  39.         }  
  40.   
  41.         public void serviceShow() throws RemoteException {  
  42.             Log.i(TAG, "___________serviceShow()");  
  43.             testClients(null);  
  44.         }  
  45.   
  46.     };  
  47.   
  48.     @Override  
  49.     public IBinder onBind(Intent intent) {  
  50.         // TODO Auto-generated method stub  
  51.         return mBinder;  
  52.     }  
  53.   
  54.     /* 
  55.      * Test the clients. 
  56.      */  
  57.     public void testClients(IEmilyServiceCallBack cb) {  
  58.         if (cb != null) {  
  59.             Log.i(TAG, "cb != null");  
  60.             try {  
  61.                 cb.serviceCallBackShow();  
  62.             } catch (RemoteException e) {  
  63.             }  
  64.         } else {  
  65.             // Broadcast to all clients the new value.  
  66.             final int count = mCallbacks.beginBroadcast();  
  67.             for (int i=0; i < count; i++) {  
  68.                 try {  
  69.                     Log.i(TAG, "onServiceShowFinished____i = " + i);  
  70.                     mCallbacks.getBroadcastItem(i).serviceCallBackShow();  
  71.                 } catch (RemoteException e) {  
  72.                 }  
  73.             }  
  74.             mCallbacks.finishBroadcast();  
  75.         }  
  76.     }  
  77. }  

3. 当一个客户端调bindservice()去连接service的时候,客户端调用onServiceConected()回调方法。

 

Client

  1. package com.example.emilysecondclient;  
  2.   
  3. import com.example.fwk.IEmilyService;  
  4. import com.example.fwk.IEmilyServiceCallBack;  
  5.   
  6. import android.os.Bundle;  
  7. import android.os.IBinder;  
  8. import android.os.RemoteException;  
  9. import android.app.Activity;  
  10. import android.content.ComponentName;  
  11. import android.content.Context;  
  12. import android.content.Intent;  
  13. import android.content.ServiceConnection;  
  14. import android.util.Log;  
  15. import android.view.Menu;  
  16. import android.view.View;  
  17. import android.view.View.OnClickListener;  
  18. import android.widget.Button;  
  19.   
  20. public class MainActivity extends Activity {  
  21.     private static String TAG = "EmilySecondClient";  
  22.     private static String ACTION_START_EMILY_SERVICE = "android.intent.action.EMILY_SERVICE";  
  23.     private IEmilyService mEmilyService = null;  
  24.   
  25.     @Override  
  26.     public void onCreate(Bundle savedInstanceState) {  
  27.         super.onCreate(savedInstanceState);  
  28.         setContentView(R.layout.activity_main);  
  29.   
  30.         // When the client call the bindService() to connect to Emily service,  
  31.         // the client's onServiceConnected() callback receives IBinder that the  
  32.         // client can use to communicate with the service.  
  33.         Intent serviceIntent = new Intent(ACTION_START_EMILY_SERVICE);  
  34.         bindService(serviceIntent, mEmilyServiceConnection, Context.BIND_AUTO_CREATE);  
  35.   
  36.         Button button1 = (Button)findViewById(R.id.button1);  
  37.         button1.setOnClickListener(new OnClickListener() {  
  38.             public void onClick(View v) {  
  39.                 serviceShowInClient();  
  40.             }  
  41.         });  
  42.     }  
  43.   
  44.     @Override  
  45.     public boolean onCreateOptionsMenu(Menu menu) {  
  46.         getMenuInflater().inflate(R.menu.activity_main, menu);  
  47.         return true;  
  48.     }  
  49.   
  50.     private final ServiceConnection mEmilyServiceConnection = new ServiceConnection() {  
  51.         // Called when the connection with the service is established.  
  52.         public void onServiceConnected(ComponentName className, IBinder service) {  
  53.             Log.i(TAG, "call service connected");  
  54.             mEmilyService = IEmilyService.Stub.asInterface(service);  
  55.             // We want to monitor the service for as long as we are  
  56.             // connected to it.  
  57.             try {  
  58.                 mEmilyService.registerCallback(mCallBack);  
  59.             } catch (RemoteException e) {  
  60.             }  
  61.         }  
  62.   
  63.         public void onServiceDisconnected(ComponentName className) {  
  64.             Log.i(TAG, "call service disconnected");  
  65.             mEmilyService = null;  
  66.         }  
  67.     };  
  68.   
  69.     private final IEmilyServiceCallBack.Stub mCallBack = new IEmilyServiceCallBack.Stub() {  
  70.         public void serviceCallBackShow() throws RemoteException {  
  71.             Log.i(TAG, "___________serviceCallBackShow()");  
  72.         }  
  73.   
  74.     };  
  75.   
  76.     private void serviceShowInClient() {  
  77.         try {  
  78.             mEmilyService.serviceShow();  
  79.         } catch (RemoteException e) {  
  80.             e.printStackTrace();  
  81.         }  
  82.     }  
  83. }  

以上只贴出来了一个Client的代码,另外一个client代码是类似的。

下面是运行出的log.

 

The log

  1. I/EmilyFirstClient( 4163): call service connected  
  2. I/EmilyService( 4084): Binder API: registerCallback()  
  3. I/EmilyService( 4084): ___________serviceShow()  
  4.   
  5.   
  6.   
  7. I/EmilySecondClient( 4206): call service connected  
  8. I/EmilyService( 4084): Binder API: registerCallback()  
  9. I/EmilyService( 4084): ___________serviceShow()  
  10.   
  11.   
  12.   
  13.   
  14. I/EmilyFirstClient( 6830): call service connected  
  15. I/EmilyService( 6711): ___________registerCallback()  
  16. I/EmilyService( 6711): ___________serviceShow()  
  17. I/EmilyService( 6711): onServiceShowFinished____i = 0  
  18. I/EmilyFirstClient( 6830): ___________serviceCallBackShow()  
  19.   
  20.   
  21.   
  22.   
  23.   
  24. I/EmilySecondClient( 6931): call service connected  
  25. I/EmilyService( 6711): ___________registerCallback()  
  26. I/EmilyService( 6711): ___________serviceShow()  
  27. I/EmilyService( 6711): onServiceShowFinished____i = 0  
  28. I/EmilySecondClient( 6931): ___________serviceCallBackShow()  

还是要好好研究下:

http://developer.android.com/guide/components/aidl.html 

 

 

抱歉!评论已关闭.