【移动开发】AIDL中callback的实现

来源:互联网 发布:千客盟 互刷软件 编辑:程序博客网 时间:2024/05/17 08:56

 AIDL实现就可以在客户端中调用服务端的方法,并传递数据到服务端,也可以服务端传递数据过来;但是如果要从服务端去调用客户端的方法,那么就需要注册callback!

 

抄自和源码:http://zxl-ong.iteye.com/blog/736888

 

前面的文件讲到用AIDL来实现进程间的通信,但是只讲到客户端调用服务端的方法,现在来看看服务端对客户端方法的调用callback!

服务端对客户端的调用主要用到了RemoteCallbackList这个类;

一、服务端

首先必须写客户端对服务端调用的一个AIDL文件:

[html] view plaincopy
  1. package net.blogjava.mobile.complex.type.aidl;  
  2. import net.blogjava.mobile.complex.type.aidl.Product;  
  3. import net.blogjava.mobile.complex.type.aidl.ITaskCallback;  
  4. interface IMyService    
  5. {    
  6.     //客户端对服务端调用的方法                                                                                                         Map getMap(in String country, in Product product);  
  7.     Product getProduct();       
  8.     void getProduc(out Product product);  
  9.       
  10.     //用来注册回调的对象  
  11.      void registerCallback(ITaskCallback cb);     
  12.     void unregisterCallback(ITaskCallback cb);  
  13. }      


这个文件会生成一个.java文件;

 

然后再新建一个类并extend service,用于AIDL的服务;在服务中重写onbind()函数并实现AIDL中的方法:

[html] view plaincopy
  1. public class MyServiceImpl extends IMyService.Stub  
  2. {  
  3.     @Override  
  4.     public Product getProduct() throws RemoteException  
  5.     {  
  6.           
  7.         Product product = new Product();  
  8.         product.setId(1234);  
  9.         product.setName("汽车");  
  10.         product.setPrice(31000);   
  11.         return product;  
  12.     }  
  13.   
  14.     @Override  
  15.     public void getProduc(Product product) throws RemoteException {  
  16.         if(product == null) product = new Product();  
  17.         product.setId(1234);  
  18.         product.setName("飞机");  
  19.         product.setPrice(62000);   
  20.     }  
  21.   
  22.     @Override  
  23.     public Map getMap(String country, Product product)  
  24.             throws RemoteException  
  25.     {  
  26.         Map map = new HashMap<String, String>();  
  27.         map.put("country", country);  
  28.         map.put("id", product.getId());  
  29.         map.put("name", product.getName());  
  30.         map.put("price", product.getPrice());  
  31.         map.put("product", product);  
  32.         return map;  
  33.     }  
  34.   
  35.     @Override  
  36.     public void registerCallback(ITaskCallback cb) throws RemoteException {  
  37.         if(cb != null)  
  38.             mCallbacks.register(cb);  
  39.     }     
  40.   
  41.     @Override  
  42.     public void unregisterCallback(ITaskCallback cb) throws RemoteException {  
  43.         if(cb != null)  
  44.             mCallbacks.unregister(cb);  
  45.     }  
  46. }  
  47.   
  48. @Override  
  49. public IBinder onBind(Intent intent)  
  50. {         
  51.     return new MyServiceImpl();  
  52. }                                                                                        private RemoteCallbackList<ITaskCallback> mCallbacks;  


mCallbacks.register(cb);是RemoteCallbackList的一个方法;客户端中必须在得到这个service后,调用这个方法来注册回调函数;

 

客户端注册成功后,便可以通过以下方法来调用回调函数:

[html] view plaincopy
  1. void callback(int startId) {  
  2.         //返回boardcast中的回调函数的个数  
  3.         final int N = mCallbacks.beginBroadcast();  
  4.         Log.i(TAG, "mCallbacks.beginBroadcast() :" + N);  
  5.         for (int i = 0; i < N; i++) {  
  6.             Log.i(TAG, "I = "+String.valueOf(i));  
  7.             try {  
  8.                 mCallbacks.getBroadcastItem(i).clientTackCallBack(startId);  
  9.             } catch (RemoteException e) {  
  10.                 // The RemoteCallbackList will take care of removing  
  11.                 // the dead object for us.  
  12.             }  
  13.         }  
  14.         mCallbacks.finishBroadcast();  
  15.     }  


mCallbacks.beginBroadcast();返回的是注册的回调函数的个数;

 

二、客户端

客户端必须先把AIDL文件复制过来,或者直接复制生成的gen/.java到src下;

首先是得到进程共享:

[html] view plaincopy
  1. bindService(new Intent("net.blogjava.mobile.complex.type.aidl.IMyService"),  
  2.                         serviceConnection, Context.BIND_AUTO_CREATE);  
[html] view plaincopy
  1. <p>private ServiceConnection serviceConnection = new ServiceConnection()  
  2.  {</p><p>  @Override  
  3.   public void onServiceConnected(ComponentName name, IBinder service)  
  4.   {  
  5.    myService = IMyService.Stub.asInterface(service);  
  6.    try {  
  7.     myService.registerCallback(mCallback);  
  8.    } catch (RemoteException e) {  
  9.     e.printStackTrace();  
  10.    }  
  11.    btnInvokeAIDLService.setEnabled(true);</p><p>  }</p><p>  @Override  
  12.   public void onServiceDisconnected(ComponentName name)  
  13.   {  
  14.    // TODO Auto-generated method stub</p><p>  }</p>  

在得到服务端的服务的时候必须注册回调函数;以下是回调的实现:

[html] view plaincopy
  1. private ITaskCallback mCallback = new ITaskCallback.Stub() {  
  2.     @Override  
  3.     public void clientTackCallBack(int actionId) throws RemoteException {  
  4.         Log.i(TAG, "actionId :" + actionId);  
  5.     }  
  6.    };  


这样在服务端中调用callback()函数就是调用了这里的clientTackCallBack(),从而实现了服务端对客户端的回调;

0 0
原创粉丝点击