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


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

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

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

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

    一、服务端

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

    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中的方法:

    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后,调用这个方法来注册回调函数;

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

    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下;

    首先是得到进程共享:

    1. bindService(new Intent("net.blogjava.mobile.complex.type.aidl.IMyService"),  
    2.                         serviceConnection, Context.BIND_AUTO_CREATE);  
    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>  

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

    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(),从而实现了服务端对客户端的回调;

  • 相关阅读:
    算法的定义
    用标准的CSS定义你的表格样式
    Mysql存储过程中临时表的建立及游标遍历
    Ubuntu10.0下编译qt版webkit
    指针函数的一个范例,在单片机上运用它能让您的程序结构更明朗清晰,层次感强
    你若不自己爬上来,我就把你打死在水中——分享三个跟管理有关的小故事
    Windows 上使用 Github 手记
    IIS应用程序池由服务器引起常见错误号的原因分析及解决方法
    如何实施好基于MOSS的企业搜索项目(上)
    如何做好项目经理
  • 原文地址:https://www.cnblogs.com/xiaomaohai/p/6158017.html
Copyright © 2020-2023  润新知