这几天搞了搞AIDL,终于弄明白了在AIDL中让Service调用Activity的方法
代码:
首先建立一个ICallback.aidl文件,作为Activity中的回调方法




1 
     
   package 
    com.zhang.test.service;
 
   2 
   
 
   3 
     
   interface 
    ICallback {
 
   4 
     
   void 
    showResult( 
   int 
    result);
 
   5 
    }



然后再建立一个IService.aidl用来在Activity中接收Service回调,以及在Service中onBind时返回的Binder
注意:aidl中import不能写com.xxx.*,要写全类的路径




1 
     
   package 
    com.zhang.test.service;
 
   2 
   
 
   3 
     
   import 
    com.zhang.test.service.ICallback;
 
   4 
   
 
   5 
     
   interface 
    IService {
 
   6 
     
   void 
    registerCallback(ICallback cb);
 
   7 
     
   void 
    unregisterCallback(ICallback cb);
 
   8 
    }



接下来是service:
MainService.java




1 
     
   package 
    com.zhang.test.service;
 
    2 
   
 
    3 
     
   import 
    android.app.Service;
 
    4 
     
   import 
    android.content.Intent;
 
    5 
     
   import 
    android.os.Handler;
 
    6 
     
   import 
    android.os.IBinder;
 
    7 
     
   import 
    android.os.Message;
 
    8 
     
   import 
    android.os.RemoteCallbackList;
 
    9 
     
   import 
    android.os.RemoteException;
 
   10 
     
   import 
    android.util.Log;
 
   11 
   
 
   12 
     
   public 
     
   class 
    MainService  
   extends 
    Service {
 
   13 
   
 
   14 
     
   private 
     
   static 
     
   final 
    String TAG  
   = 
     
   " 
   MainService 
   " 
   ;
 
   15 
   
 
   16 
     
   private 
    RemoteCallbackList 
   < 
   icallback 
   > 
    mCallbacks  
   = 
     
   new 
    RemoteCallbackList 
   < 
   icallback 
   > 
   ();
 
   17 
   
 
   18 
     
   private 
    IService.Stub mBinder  
   = 
     
   new 
    IService.Stub() {
 
   19 
   
 
   20 
    @Override
 
   21 
     
   public 
     
   void 
    unregisterCallback(ICallback cb){
 
   22 
     
   if 
   (cb  
   != 
     
   null 
   ) {
 
   23 
    mCallbacks.unregister(cb);
 
   24 
    }
 
   25 
    }
 
   26 
   
 
   27 
    @Override
 
   28 
     
   public 
     
   void 
    registerCallback(ICallback cb){
 
   29 
     
   if 
   (cb  
   != 
     
   null 
   ) {
 
   30 
    mCallbacks.register(cb);
 
   31 
    }
 
   32 
    }
 
   33 
    };
 
   34 
   
 
   35 
    @Override
 
   36 
     
   public 
    IBinder onBind(Intent intent) {
 
   37 
    Log.d(TAG,  
   " 
   onBind 
   " 
   );
 
   38 
     
   return 
    mBinder;
 
   39 
    }
 
   40 
   
 
   41 
    @Override
 
   42 
     
   public 
     
   void 
    onCreate() {
 
   43 
    Log.d(TAG,  
   " 
   onCreate 
   " 
   );
 
   44 
     
   // 
   这里不知道为什么,直接使用callback方法回调showResult
 
   45 
     
   // 
   mCallbacks.beginBroadcast()是0,需要用handler延迟1000毫秒
 
   46 
     
   // 
   也许是在activity中binService太耗时的原因? 
   
 
   47 
     
    mHandler.sendEmptyMessageDelayed( 
   0 
   ,  
   1000 
   );
 
   48 
     
   super 
   .onCreate();
 
   49 
    }
 
   50 
   
 
   51 
    @Override
 
   52 
     
   public 
     
   void 
    onDestroy() {
 
   53 
    mHandler.removeMessages( 
   0 
   );
 
   54 
    mCallbacks.kill();
 
   55 
     
   super 
   .onDestroy();
 
   56 
    }
 
   57 
   
 
   58 
     
   private 
     
   void 
    callBack() {
 
   59 
     
   int 
    N  
   = 
    mCallbacks.beginBroadcast();
 
   60 
     
   try 
    {
 
   61 
     
   for 
    ( 
   int 
    i  
   = 
     
   0 
   ; i  
   < 
    N; i 
   ++ 
   ) {
 
   62 
    mCallbacks.getBroadcastItem(i).showResult(i);
 
   63 
    }
 
   64 
    }  
   catch 
    (RemoteException e) {
 
   65 
    Log.e(TAG,  
   "" 
   , e);
 
   66 
    }
 
   67 
    mCallbacks.finishBroadcast();
 
   68 
    }
 
   69 
   
 
   70 
     
   private 
    Handler mHandler  
   = 
     
   new 
    Handler() {
 
   71 
   
 
   72 
    @Override
 
   73 
     
   public 
     
   void 
    handleMessage(Message msg) {
 
   74 
    callBack();
 
   75 
     
   super 
   .handleMessage(msg);
 
   76 
    }
 
   77 
    };
 
   78 
    }
 
   79 
     
   </ 
   icallback 
   ></ 
   icallback 
   >



然后是activity:




1 
     
   package 
    com.zhang.test;
 
    2 
   
 
    3 
     
   import 
    android.app.Activity;
 
    4 
     
   import 
    android.content.ComponentName;
 
    5 
     
   import 
    android.content.Context;
 
    6 
     
   import 
    android.content.Intent;
 
    7 
     
   import 
    android.content.ServiceConnection;
 
    8 
     
   import 
    android.os.Bundle;
 
    9 
     
   import 
    android.os.IBinder;
 
   10 
     
   import 
    android.os.RemoteException;
 
   11 
     
   import 
    android.util.Log;
 
   12 
   
 
   13 
     
   import 
    com.zhang.test.service.ICallback;
 
   14 
     
   import 
    com.zhang.test.service.IService;
 
   15 
     
   import 
    com.zhang.test.service.MainService;
 
   16 
   
 
   17 
     
   public 
     
   class 
    MainActivity  
   extends 
    Activity {
 
   18 
   
 
   19 
     
   private 
     
   static 
     
   final 
    String TAG  
   = 
     
   " 
   MainActivity 
   " 
   ;
 
   20 
   
 
   21 
     
   private 
    IService mService;
 
   22 
   
 
   23 
     
   /** 
    Called when the activity is first created.  
   */ 
   
 
   24 
    @Override
 
   25 
     
   public 
     
   void 
    onCreate(Bundle savedInstanceState) {
 
   26 
     
   super 
   .onCreate(savedInstanceState);
 
   27 
    setContentView(R.layout.main);
 
   28 
    Intent i  
   = 
     
   new 
    Intent( 
   this 
   , MainService. 
   class 
   );
 
   29 
    bindService(i, mConnection, Context.BIND_AUTO_CREATE);
 
   30 
    }
 
   31 
   
 
   32 
    @Override
 
   33 
     
   protected 
     
   void 
    onDestroy() {
 
   34 
     
   if 
   (mService 
   != 
   null 
   ){
 
   35 
     
   try 
    {
 
   36 
    mService.unregisterCallback(mCallback);
 
   37 
    }  
   catch 
    (RemoteException e) {
 
   38 
    Log.e(TAG,  
   "" 
   , e);
 
   39 
    }
 
   40 
    }
 
   41 
     
   // 
   destroy的时候不要忘记unbindService 
   
 
   42 
     
    unbindService(mConnection);
 
   43 
     
   super 
   .onDestroy();
 
   44 
    }
 
   45 
   
 
   46 
     
   /** 
   
 
   47 
    * service的回调方法
 
   48 
     
   */ 
   
 
   49 
     
   private 
    ICallback.Stub mCallback  
   = 
     
   new 
    ICallback.Stub() {
 
   50 
   
 
   51 
    @Override
 
   52 
     
   public 
     
   void 
    showResult( 
   int 
    result) {
 
   53 
    Log.d(TAG,  
   " 
    result :  
   " 
     
   + 
    result);
 
   54 
    }
 
   55 
    };
 
   56 
   
 
   57 
     
   /** 
   
 
   58 
    * 注册connection
 
   59 
     
   */ 
   
 
   60 
     
   private 
    ServiceConnection mConnection  
   = 
     
   new 
    ServiceConnection() {
 
   61 
   
 
   62 
    @Override
 
   63 
     
   public 
     
   void 
    onServiceDisconnected(ComponentName name) {
 
   64 
    Log.d(TAG,  
   " 
   onServiceDisconnected 
   " 
   );
 
   65 
    mService  
   = 
     
   null 
   ;
 
   66 
    }
 
   67 
   
 
   68 
    @Override
 
   69 
     
   public 
     
   void 
    onServiceConnected(ComponentName name, IBinder service) {
 
   70 
    Log.d(TAG,  
   " 
   onServiceConnected 
   " 
   );
 
   71 
    mService  
   = 
    IService.Stub.asInterface(service);
 
   72 
     
   try 
    {
 
   73 
    mService.registerCallback(mCallback);
 
   74 
    }  
   catch 
    (RemoteException e) {
 
   75 
    Log.e(TAG,  
   "" 
   , e);
 
   76 
    }
 
   77 
    }
 
   78 
    };
 
   79 
    }


最后不要忘记在manifest中加上service标记:




1 
     
   < 
   service android:name 
   = 
   " 
   .service.MainService 
   " 
   > 
   
 
   2 
     
   </ 
   service 
   >



总结:


通过aidl总算实现了Service与Activity的通信,写起来麻烦点,使用诸如ContentProvider,Broadcast等也可以实现.


这样做很像是在使用MVC设计模式(Activity负责View,Service以及其他类负责 Model,aidl(ServiceConnection)负责Controller),其实我对于aidl也是一知半解- -,明天研究下如何让activity去调用service中的方法.