Android启动Service有两种方法,一种是startService,一种是bindService。生命周期如下:
执行startService时,调用者如果没有stopService,Service会一直在后台运行。多次调用startService,该Service只能被创建一次,即该Service的onCreate方法只会被调用一次。但是每次调用startService,onStartCommand方法都会被调用。
执行bindService时,调用者调用unbindService方法或者调用者Context不存在了(如Activity被finish了)。第一次执行bindService时,onCreate和onBind方法会被调用,但是多次执行bindService时,onCreate和onBind方法并不会被多次调用,即并不会多次创建服务和绑定服务。 多个组件可以同时绑定到该服务,但全部取消绑定后,该服务即会被销毁。
既使用startService又使用bindService的情况,需要unbindService和stopService同时调用才会终止Service。
Activity与Service交互有两种方法:一种是使用broadcast,另一种是使用bindService。本文只介绍bindService方法。
public class MsgService extends Service {
public MsgService() {
} /**
* 进度条的最大值
*/
public static final int MAX_PROGRESS = 100;
/**
* 进度条的进度值
*/
private int progress = 0; /**
* 增加get()方法,供Activity调用
*
* @return 下载进度
*/
public int getProgress() {
return progress;
} /**
* 模拟下载任务,每秒钟更新一次
*/
public void startDownLoad(){
new Thread(new Runnable() { @Override
public void run() {
while(progress < MAX_PROGRESS){
progress += 5; //进度发生变化通知调用方
if(onProgressListener != null){
onProgressListener.onProgress(progress);
} try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
} }
}
}).start();
} @Override
public IBinder onBind(Intent intent) {
return new MyBinder();
} public class MyBinder extends Binder {
public MsgService getService() {
return MsgService.this;
}
} public interface OnProgressListener {
void onProgress(int progress);
} /**
* 更新进度的回调接口
*/
private OnProgressListener onProgressListener; /**
* 注册回调接口的方法,供外部调用
*
* @param onProgressListener
*/
public void setOnProgressListener(OnProgressListener onProgressListener) {
this.onProgressListener = onProgressListener;
} }
public class MainActivity extends Activity { private Button button19; private MsgService msgService;
private int progress = 0;
private ProgressBar mProgressBar; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); btnExec = (Button) findViewById(R.id.btnExec);
button19 = (Button) findViewById(R.id.button19);
mProgressBar = (ProgressBar) findViewById(R.id.progressBar); button19.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
msgService.startDownLoad();
}
}); Intent intent = new Intent(this, MsgService.class);
bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE); } ServiceConnection mServiceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
msgService = ((MsgService.MyBinder) iBinder).getService(); msgService.setOnProgressListener(new MsgService.OnProgressListener() {
@Override
public void onProgress(int progress) {
mProgressBar.setProgress(progress);
}
});
} @Override
public void onServiceDisconnected(ComponentName componentName) { }
}; @Override
protected void onDestroy() { unbindService(mServiceConnection);
super.onDestroy();
}
}
例子中,MsgService模拟耗时的下载任务,MainActivity 绑定服务,通过注册OnProgressListener回调获取下载进度,更新进度条。
本例子Activity和Service是在同一个进程中,对于跨进程调用Service需要使用到AIDL技术。