在MainActivity中启动一个Service,Service中开启一个倒计时,在CountDownActivity中获取倒计时信息并更新UI。通过Binder实现Service与Activity的通信。 1.CountDownService
import android.app.Service;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Binder;
import android.os.CountDownTimer;
import android.os.IBinder;
public class CountDownService extends Service{
private MyBinder myBinder = new MyBinder();
private OnCountDownListener onCountDownListener;
private MyCountDownTimer cdTimer;
private int min = 60;
private boolean stopped = true;
public void setOnCountDownListener(OnCountDownListener onCountDownListener) {
this.onCountDownListener = onCountDownListener;
}
<span style="white-space:pre"> </span>/**
<span style="white-space:pre"> </span> * 倒计时是否停止
<span style="white-space:pre"> </span> * @return
<span style="white-space:pre"> </span> */
public boolean isStopped() {
return stopped;
}
@Override
public void onCreate() {
super.onCreate();
}
@Override
public IBinder onBind(Intent arg0) {
return myBinder;
}
@Override
/**
* 为重新绑定是能调用该生命周期,onUnbind()需要返回return true;
*/
public void onRebind(Intent intent) {
System.out.println("CountDownService.onRebind()");
super.onRebind(intent);
}
@Override
public boolean onUnbind(Intent intent) {
System.out.println("CountDownService.onUnbind()");
return super.onUnbind(intent);
}
@Override
public void unbindService(ServiceConnection conn) {
System.out.println("CountDownService.unbindService()");
super.unbindService(conn);
}
<span style="white-space:pre"> </span>/**
<span style="white-space:pre"> </span> * 开始倒计时
<span style="white-space:pre"> </span> */
public void startCountDown(){
cdTimer = new MyCountDownTimer(min * 1000, 1000);
cdTimer.start();
stopped = false;
if(onCountDownListener != null)onCountDownListener.onStartCountDown();
}
private class MyCountDownTimer extends CountDownTimer{
public MyCountDownTimer(long millisInFuture, long countDownInterval) {
super(millisInFuture, countDownInterval);
}
@Override
public void onFinish() {
if(onCountDownListener != null)onCountDownListener.onStopCountDown();
stopped = true;
cdTimer.cancel();
}
@Override
public void onTick(long arg0) {
if(onCountDownListener != null)onCountDownListener.onProgress((int)arg0 / 1000);
}
}
public class MyBinder extends Binder{
public CountDownService getService(){
return CountDownService.this;
}
}
public interface OnCountDownListener{
public void onStartCountDown();
public void onProgress(int cd);
public void onStopCountDown();
}
@Override
public void onDestroy() {
cdTimer.cancel();
stopSelf();
super.onDestroy();
}
}
内部类MyBinder继承自Binder,只有一个方法,就是获取到当前CoundDownService实例。
倒计时信息能被Activity收到是通过回调实现的。接口OnCountDownListener,需要在接收倒计时信息的Activity中实现,以获得倒计时的开始、进行、结束。
2.MainActivity
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;
public class MainActivity extends Activity {
private Button bnStart;
private CountDownService cdService;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.bn_bind).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
bindService(new Intent(MainActivity.this, CountDownService.class), svcConn, Context.BIND_AUTO_CREATE);
bnStart.setEnabled(true);
}
});
findViewById(R.id.bn_unbind).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
unbindService(svcConn);
bnStart.setEnabled(false);
}
});
bnStart = (Button) findViewById(R.id.bn_start);
bnStart.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if(cdService.isStopped()){
cdService.startCountDown();
} else{
Toast.makeText(MainActivity.this, "cd has started", Toast.LENGTH_SHORT).show();
}
startActivity(new Intent(MainActivity.this, CountDownActivity.class));
}
});
}
private ServiceConnection svcConn = new ServiceConnection() {
@Override
public void onServiceDisconnected(ComponentName name) {
}
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
cdService = ((CountDownService.MyBinder)service).getService();
}
};
@Override
protected void onDestroy() {
unbindService(svcConn);
cdService.onDestroy();
super.onDestroy();
};
}
界面主要就是3个按钮,一个绑定,一个解除绑定,一个开始Service中的倒计时。
bindService()中需要传递一个ServiceConnection对象,通过其中的onServiceConnected()拿到Service中的Binder,本例中在通过Binder获取到Service实例。
点击开始按钮,其中倒计时,并打开一个新的Activity,在这个Activity中根据倒计时更新UI。
3.CountDownActivity
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import com.example.demo_servicebinder.CountDownService.OnCountDownListener;
public class CountDownActivity extends Activity implements OnCountDownListener{
private TextView tv;
private CountDownService cdService;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_count_down);
tv = (TextView) findViewById(R.id.tv_cd);
Intent intent = new Intent(this, CountDownService.class);
bindService(intent, svcConn, Context.BIND_AUTO_CREATE);
}
private ServiceConnection svcConn = new ServiceConnection() {
@Override
public void onServiceDisconnected(ComponentName name) {
}
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
cdService = ((CountDownService.MyBinder)service).getService();
cdService.setOnCountDownListener(CountDownActivity.this);
}
};
@Override
public void onStartCountDown() {
Toast.makeText(this, "start", Toast.LENGTH_SHORT).show();
}
@Override
public void onProgress(int cd) {
tv.setText(cd + "秒后结束");
}
@Override
public void onStopCountDown() {
Toast.makeText(this, "onstop", Toast.LENGTH_SHORT).show();
}
@Override
protected void onDestroy() {
unbindService(svcConn);
super.onDestroy();
}
}
首先,需要绑定已经启动的Service,得到CountDownService。
这个Activity实现OnCountDownListener接口,实现那三个方法,就可以在相应的方法里更新UI了。
onCreate中对bindService的调用应该是异步的,所以不能够立即建立service连接已获取得到绑定结果。也就是说不能在onCreate的bindService后紧接着执行绑定后的结果,这个时候service对象还没有被获取到,是一个空的。绑定后要执行的方法应该写在onServiceConnected里面。
onCreate中对bindService的调用应该是异步的,所以不能够立即建立service连接已获取得到绑定结果。也就是说不能在onCreate的bindService后紧接着执行绑定后的结果,这个时候service对象还没有被获取到,是一个空的。绑定后要执行的方法应该写在onServiceConnected里面。