Service和Activity通讯的3种常用方式示例
16lz
2021-01-24
一般的Android业务开发中,Service的使用十分常见。稍微复杂点的业务逻辑,都需要Serivice在执行某些耗时操作后通知Activity。总结常见的三种方法。
分别是:(1)binder持有Activity的Handler对象,或者持有一个Activity的callbackInterface.
(2)AIDL实现,完美支持IPC。
(3)startService+broadcastReceiver实现。
另外还有几种不推荐的方式,都有很高的局限性。比如Service执行后的结果持久化,通过startActivity在目标Activity中的OnNewIntent()处理(需要Activity是单例的)。
(1)Binder持有Activity的Handler,这里推荐Handler弱引用Activity实现。
关键代码如下:
public class WeakReferenceHandlerActivity extends Activity {private MyHandler mHandler;public static int FLAG = 10;public ProgressBar progressBar;private Button bindButton;private Button nextButton;private UseHandlerService.MyBinder myBinder; @Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.handler_layout);progressBar = (ProgressBar)this.findViewById(R.id.progress);bindButton = (Button)this.findViewById(R.id.bind);nextButton = (Button)this.findViewById(R.id.next);mHandler = new MyHandler(this);bindButton.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {bindService();Log.d("","startDownLoad() --> click");}});nextButton.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {startActivity(new Intent(WeakReferenceHandlerActivity.this,AndroidAidlActivity.class));}});} private ServiceConnection connection = new ServiceConnection() { @Override public void onServiceDisconnected(ComponentName name) { } @Override public void onServiceConnected(ComponentName name, IBinder service) { Log.d("","startDownLoad() --> onbind"); myBinder = (UseHandlerService.MyBinder) service; myBinder.setCallBackHandler(mHandler); myBinder.startDownLoad(); } }; @Overrideprotected void onResume() { super.onResume();} @Overrideprotected void onPause() { unBindService();super.onPause();} public void bindService(){ Intent bindIntent = new Intent(this, UseHandlerService.class); bindService(bindIntent, connection, BIND_AUTO_CREATE); } public void unBindService(){ unbindService(connection); } @Overrideprotected void onDestroy() {// Remove all Runnable and Message.mHandler.removeCallbacksAndMessages(null);super.onDestroy();}public MyHandler getHandler(){return mHandler;}public class MyHandler extends Handler {// WeakReference to the outer class's instance.private WeakReference mOuter;public MyHandler(WeakReferenceHandlerActivity activity) {mOuter = new WeakReference(activity);}@Overridepublic void handleMessage(Message msg) {WeakReferenceHandlerActivity outer = mOuter.get();if (outer != null) {// Do something with outer as your wish.if(!outer.isFinishing()){int progress = msg.what;progressBar.setProgress(progress);}}}}}
public class UseHandlerService extends Service{/** * 进度条的最大值 */public static final int MAX_PROGRESS = 100; /** * 进度条的进度值 */private int progress = 0;/** * 更新进度的回调接口 */private MyHandler myHandler;private MyBinder mBinder = new MyBinder(); private String TAG = "UseHandlerService";/** * 注册回调接口的方法,供外部调用 * @param onProgressListener */public void setHandler(MyHandler handler) {myHandler = handler;}/** * 增加get()方法,供Activity调用 * @return 下载进度 */public int getProgress() {return progress;}@Override public void onCreate() { super.onCreate(); Log.d(TAG, "onCreate() executed"); } @Override public int onStartCommand(Intent intent, int flags, int startId) { Log.d(TAG, "onStartCommand() executed"); return super.onStartCommand(intent, flags, startId); } @Override public void onDestroy() { super.onDestroy(); Log.d(TAG, "onDestroy() executed"); } /** * 返回一个Binder对象 */@Overridepublic IBinder onBind(Intent intent) {return mBinder;}public class MyBinder extends Binder{/** * 获取当前Service的实例 * @return */public UseHandlerService getService(){return UseHandlerService.this;}public void setCallBackHandler(MyHandler handler){myHandler = handler;}public void startDownLoad(){Log.d("","startDownLoad() inBinder-->");new Thread(new Runnable() {public void run() {while(progress < MAX_PROGRESS){progress += 5;Log.d("","startDownLoad() run-->");//进度发生变化通知调用方if(myHandler != null){myHandler.sendEmptyMessage(progress);}try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}}}).start();}}}
弱引用的实现,是出于防止Service不销毁,一直导致目标Activity也不能会回收的考虑。
(2)AIDL实现,同样还是进度条的UI更新。
public class AndroidAidlActivity extends Activity { /** Called when the activity is first created. */public static final int MAX_PROGRESS = 100; /** * 进度条的进度值 */private int progress = 0;public ProgressBar progressBar;private Button bindButton;private MyAIDLService mService; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.handler_layout); progressBar = (ProgressBar)this.findViewById(R.id.progress); bindButton = (Button)this.findViewById(R.id.bind);bindButton.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {bindService();Log.d("","startDownLoad() --> click");}});this.findViewById(R.id.next).setVisibility(View.GONE); } private ICallBack.Stub mCallback = new ICallBack.Stub() { @Override public void showResult(final int result) { Log.d("", "showresult -->" + result); progressBar.setProgress(result); } }; private ServiceConnection connection = new ServiceConnection() { @Override public void onServiceDisconnected(ComponentName name) { mService = null; } @Override public void onServiceConnected(ComponentName name, IBinder service) { Log.d("","startDownLoad() --> onbind"); mService = MyAIDLService.Stub.asInterface(service); try { mService.registerCallback(mCallback); mService.startDownload(); } catch (RemoteException e) { Log.e("", "", e); } } }; @Overrideprotected void onResume() {super.onResume();} @Overrideprotected void onPause() { unBindService();super.onPause();} public void bindService(){ Intent bindIntent = new Intent(this, AidlService.class); bindService(bindIntent, connection, BIND_AUTO_CREATE); } public void unBindService(){ unbindService(connection); } @Overrideprotected void onDestroy() {// Remove all Runnable and Message.super.onDestroy();}}public class AidlService extends Service {private RemoteCallbackList mCallbacks = new RemoteCallbackList();MyAIDLService.Stub mBinder = new Stub() {@Overridepublic void registerCallback(ICallBack cb) throws RemoteException {if(cb != null) { mCallbacks.register(cb);}}@Overridepublic void unregisterCallback(ICallBack cb) throws RemoteException {if(cb != null) { mCallbacks.unregister(cb);}}@Overridepublic void startDownload() throws RemoteException {Log.d("","startDownLoad() inBinder-->");new Thread(new Runnable() {public void run() {while(progress < MAX_PROGRESS){progress += 5;Log.d("","startDownLoad() run-->");//进度发生变化通知调用方if(mHandler != null){//TODOmHandler.sendEmptyMessage(progress);}try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}}}).start();}};/** * 进度条的最大值 */public static final int MAX_PROGRESS = 100; /** * 进度条的进度值 */private int progress = 0;/** * 更新进度的回调接口 */private String TAG = "UseHandlerService";/** * 增加get()方法,供Activity调用 * @return 下载进度 */public int getProgress() {return progress;}@Override public void onCreate() { super.onCreate(); //mHandler.sendEmptyMessageDelayed(0, 1000); Log.d(TAG, "onCreate() executed"); } private void callBack(Message msg) {int N = mCallbacks.beginBroadcast();try { for (int i = 0; i < N; i++) { Log.d("","mCallbacks -->progress"+msg.what); mCallbacks.getBroadcastItem(i).showResult(msg.what); }} catch (RemoteException e) { Log.e(TAG, "", e);}mCallbacks.finishBroadcast();}private Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { callBack(msg); super.handleMessage(msg); }}; @Override public int onStartCommand(Intent intent, int flags, int startId) { Log.d(TAG, "onStartCommand() executed"); return super.onStartCommand(intent, flags, startId); } @Override public void onDestroy() { super.onDestroy(); Log.d(TAG, "onDestroy() executed"); } /** * 返回一个Binder对象 */@Overridepublic IBinder onBind(Intent intent) {return mBinder;}}还有两个AIDL文件package com.banking.hello;interface ICallBack { void showResult(int result);} package com.banking.hello;import com.banking.hello.ICallBack;interface MyAIDLService {void registerCallback(ICallBack cb); void unregisterCallback(ICallBack cb); void startDownload();}
这种方式,无论Service是否是remote,都可以实现高效率通讯。 (3)第三种通过Receiver非常简单,就不上代码了。
sendBroadCast,然后在Activity中注册一个相对应的内部receiver接受就可以了.
查看工程
更多相关文章
- 【Android】高效ListView
- Android(安卓)架构组件(一)——Lifecycle
- Android(安卓)调用系统相机拍照保存以及调用系统相册的方法
- 学习Android(安卓)--从现在开始
- Android(安卓)studio gradle build 太慢,有时会卡住的解决方法
- Android(安卓)TV Input Framework(TIF)--显示Tv Input
- 使用Lint 和 Annotations来提升代码质量
- Android(安卓)databinding(详解三)--自定义属性使用
- android 莫名出现Conversion to Dalvik format failed: Unable t