使用android中的AIDL让Service与Activity通信(service回调activity)

来源:互联网 发布:js indexof 最后一个 编辑:程序博客网 时间:2024/06/05 12:58
这几天搞了搞AIDL,终于弄明白了在AIDL中让Service调用Activity的方法
代码:
首先建立一个ICallback.aidl文件,作为Activity中的回调方法
  1. package com.zhang.test.service;

  2. interface ICallback {
  3. void showResult(int result);
  4. }
然后再建立一个IService.aidl用来在Activity中接收Service回调,以及在Service中onBind时返回的Binder
注意:aidl中import不能写com.xxx.*,要写全类的路径
  1. package com.zhang.test.service;

  2. import com.zhang.test.service.ICallback;

  3. interface IService {
  4.         void registerCallback(ICallback cb);
  5.         void unregisterCallback(ICallback cb);
  6. }
复制代码
接下来是service:
MainService.java
  1. package com.zhang.test.service;

  2. import android.app.Service;
  3. import android.content.Intent;
  4. import android.os.Handler;
  5. import android.os.IBinder;
  6. import android.os.Message;
  7. import android.os.RemoteCallbackList;
  8. import android.os.RemoteException;
  9. import android.util.Log;

  10. public class MainService extends Service {

  11.     private static final String TAG = "MainService";

  12.     private RemoteCallbackList<icallback> mCallbacks = new RemoteCallbackList<icallback>();

  13.     private IService.Stub mBinder = new IService.Stub() {

  14.         @Override
  15.         public void unregisterCallback(ICallback cb){
  16.             if(cb != null) {
  17.                 mCallbacks.unregister(cb);
  18.             }
  19.         }

  20.         @Override
  21.         public void registerCallback(ICallback cb){
  22.             if(cb != null) {
  23.                 mCallbacks.register(cb);
  24.             }
  25.         }
  26.     };

  27.     @Override
  28.     public IBinder onBind(Intent intent) {
  29.         Log.d(TAG, "onBind");
  30.         return mBinder;
  31.     }

  32.     @Override
  33.     public void onCreate() {
  34.         Log.d(TAG, "onCreate");
  35.         //这里不知道为什么,直接使用callback方法回调showResult
  36.         //mCallbacks.beginBroadcast()是0,需要用handler延迟1000毫秒
  37.         //也许是在activity中binService太耗时的原因?
  38.         mHandler.sendEmptyMessageDelayed(0, 1000);
  39.         super.onCreate();
  40.     }

  41.     @Override
  42.     public void onDestroy() {
  43.         mHandler.removeMessages(0);
  44.         mCallbacks.kill();
  45.         super.onDestroy();
  46.     }

  47.     private void callBack() {
  48.         int N = mCallbacks.beginBroadcast();
  49.         try {
  50.             for (int i = 0; i < N; i++) {
  51.                 mCallbacks.getBroadcastItem(i).showResult(i);
  52.             }
  53.         } catch (RemoteException e) {
  54.             Log.e(TAG, "", e);
  55.         }
  56.         mCallbacks.finishBroadcast();
  57.     }

  58.     private Handler mHandler = new Handler() {

  59.         @Override
  60.         public void handleMessage(Message msg) {
  61.             callBack();
  62.             super.handleMessage(msg);
  63.         }
  64.     };
  65. }
  66. </icallback></icallback>
复制代码
然后是activity:
  1. package com.zhang.test;

  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 com.zhang.test.service.ICallback;
  12. import com.zhang.test.service.IService;
  13. import com.zhang.test.service.MainService;

  14. public class MainActivity extends Activity {

  15.     private static final String TAG = "MainActivity";

  16.     private IService mService;

  17.     /** Called when the activity is first created. */
  18.     @Override
  19.     public void onCreate(Bundle savedInstanceState) {
  20.         super.onCreate(savedInstanceState);
  21.         setContentView(R.layout.main);
  22.         Intent i = new Intent(this, MainService.class);
  23.         bindService(i, mConnection, Context.BIND_AUTO_CREATE);
  24.     }

  25.     @Override
  26.     protected void onDestroy() {
  27.         if(mService!=null){
  28.             try {
  29.                 mService.unregisterCallback(mCallback);
  30.             } catch (RemoteException e) {
  31.                 Log.e(TAG, "", e);
  32.             }
  33.         }
  34.         //destroy的时候不要忘记unbindService
  35.         unbindService(mConnection);
  36.         super.onDestroy();
  37.     }

  38.     /**
  39.      * service的回调方法
  40.      */
  41.     private ICallback.Stub mCallback = new ICallback.Stub() {

  42.         @Override
  43.         public void showResult(int result) {
  44.             Log.d(TAG, " result : " + result);
  45.         }
  46.     };

  47.     /**
  48.      * 注册connection
  49.      */
  50.     private ServiceConnection mConnection = new ServiceConnection() {

  51.         @Override
  52.         public void onServiceDisconnected(ComponentName name) {
  53.             Log.d(TAG, "onServiceDisconnected");
  54.             mService = null;
  55.         }

  56.         @Override
  57.         public void onServiceConnected(ComponentName name, IBinder service) {
  58.             Log.d(TAG, "onServiceConnected");
  59.             mService = IService.Stub.asInterface(service);
  60.             try {
  61.                 mService.registerCallback(mCallback);
  62.             } catch (RemoteException e) {
  63.                 Log.e(TAG, "", e);
  64.             }
  65.         }
  66.     };
  67. }
最后不要忘记在manifest中加上service标记:
  1. <service android:name=".service.MainService">
  2. </service>
运行程序,查看Logcat
结果如下:

总结:
通过aidl总算实现了Service与Activity的通信,写起来麻烦点,使用诸如ContentProvider,Broadcast等也可以实现.
这样做很像是在使用MVC设计模式(Activity负责View,Service以及其他类负责 Model,aidl(ServiceConnection)负责Controller),其实我对于aidl也是一知半解- -,明天研究下如何让activity去调用service中的方法.
原创粉丝点击