一般的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;
@Override
protected 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() {
@Override
public void onClick(View v) {
bindService();
Log.d("","startDownLoad() --> click");
}
});
nextButton.setOnClickListener(new OnClickListener() {
@Override
public 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();
}
};
@Override
protected void onResume() {
super.onResume();
}
@Override
protected 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);
}
@Override
protected 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);
}
@Override
public 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对象
*/
@Override
public 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() {
@Override
public 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);
}
}
};
@Override
protected void onResume() {
super.onResume();
}
@Override
protected 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);
}
@Override
protected void onDestroy() {
// Remove all Runnable and Message.
super.onDestroy();
}
}
public class AidlService extends Service {
private RemoteCallbackList mCallbacks = new RemoteCallbackList();
MyAIDLService.Stub mBinder = new Stub() {
@Override
public void registerCallback(ICallBack cb) throws RemoteException {
if(cb != null) {
mCallbacks.register(cb);
}
}
@Override
public void unregisterCallback(ICallBack cb) throws RemoteException {
if(cb != null) {
mCallbacks.unregister(cb);
}
}
@Override
public 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){
//TODO
mHandler.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对象
*/
@Override
public 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接受就可以了.
查看工程