服务Service是Android四大组件之一,它与Activity最大的不同在于它没有界面,所以它是不可见的,它是在后台启动的,所以我们可以利用它做一些Activity做不到的事情,比如当应用退到后台时,它就可以被派上用场了。
Service有2种启动方式,分别是startService()和bindService(),相信大家都知道,今天主要来讲下它们使用上具体的区别,这里用一个计时器的Demo来演示一下:
第一步当然是新建Service类,别忘记在AndroidManifest.xml中注册,然后实现它的生命周期各个方法,这里在onCreate()时开启计时器,onDestroy()时关闭计时器,计时器怎么用这里就不讲了,onStart()已经过时了,用onStartCommand()来代替,onBind()是必须创建的,onUnbind()在解绑时会调用。这里还会新建一个Binder类,Binder类主要是onBind()来返回的,这里Binder类就是实现一个返回DemoService的功能,在其他地方绑定服务时可以得到这个Binder类,然后得到DemoService实例,最终目的就是使用这个DemoService来调用它自身的方法。
/** * DemoService * * @author yuzhentao */ public class DemoService extends Service {
private int i = 0; private Timer timer = null; private TimerTask task = null; private final DemoBinder demoBinder = new DemoBinder(); @Nullable @Override public IBinder onBind(Intent intent) {
Log.e("yuzhentao", "onBind"); return demoBinder; }
@Override public boolean onUnbind(Intent intent) {
Log.e("yuzhentao", "onUnbind"); return super.onUnbind(intent); }
@Override public void onCreate() {
super.onCreate(); Log.e("yuzhentao", "onCreate"); startTimer(); }
@Override public void onDestroy() {
super.onDestroy(); Log.e("yuzhentao", "onDestroy"); stopTimer(); }
@Override public int onStartCommand(Intent intent, int flags, int startId) {
Log.e("yuzhentao", "onStartCommand"); return super.onStartCommand(intent, flags, startId); }
public void startTimer() {
if (timer == null) {
timer = new Timer(); task = new TimerTask() {
@Override public void run() {
i++; Log.e("yuzhentao", i + ""); }
}; timer.schedule(task, 1000, 1000); }
}
public void stopTimer() {
if (timer != null) {
task.cancel(); timer.cancel(); task = null; timer = null; }
}
public int getCurrentNumber() {
return i; }
/** * DemoBinder */ public class DemoBinder extends Binder {
public DemoService getService() {
return DemoService.this; }
}
}
看看主界面中如何使用Service的,一共5个Button,分别是开始服务、停止服务、停止服务、解绑服务和获取数字,这个数字就是Service中获取的由计时器打印出来的数字。其中开始和停止服务很简单,分别调用startService()和stopService(),传入1个Intent,Intent真是四大组件的好伙伴啊,到处都要使用。bindService()和unbindService()比较复杂,需要用到ServiceConnection这个接口,通过这个接口,在服务绑定时,我们可以得到IBinder,这个IBinder就是Service的onBind()返回的Binder类,通过它可以得到Service的实例。然后将ServiceConnection传入bindService()和unbindService()即可。
/** * 主界面 * * @author yuzhentao */ public class MainActivity extends Activity implements View.OnClickListener {
private Intent intent; private DemoService demoService = null; private ServiceConnection serviceConnection = new ServiceConnection() {
@Override public void onServiceConnected(ComponentName name, IBinder service) {
demoService = ((DemoService.DemoBinder) service).getService(); }
@Override public void onServiceDisconnected(ComponentName name) {
}
}; @Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); intent = new Intent(this, DemoService.class); initView(); }
@Override public void onClick(View v) {
int viewId = v.getId(); switch (viewId) {
case R.id.button_start_service_activity_main:
startService(intent); break; case R.id.button_stop_service_activity_main:
stopService(intent); break; case R.id.button_bind_service_activity_main:
bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE); break; case R.id.button_unbind_service_activity_main:
unbindService(serviceConnection); demoService = null; break; case R.id.button_get_number_service_activity_main:
Log.e("yuzhentao", demoService.getCurrentNumber() + "'"); break; }
}
private void initView() {
findViewById(R.id.button_start_service_activity_main).setOnClickListener(this); findViewById(R.id.button_stop_service_activity_main).setOnClickListener(this); findViewById(R.id.button_bind_service_activity_main).setOnClickListener(this); findViewById(R.id.button_unbind_service_activity_main).setOnClickListener(this); findViewById(R.id.button_get_number_service_activity_main).setOnClickListener(this); }
}
下面讲下2中启动方式的区别,通过Log来看:
先说下前提,每次测试都是在我退出应用后重新进入应用的,为了避免搞晕自己。
第一种情况就是开始服务和停止服务:
03-15 15:10:30.683 16383-16383/yuzhentao.servicedemo E/yuzhentao: onCreate
03-15 15:10:30.685 16383-16383/yuzhentao.servicedemo E/yuzhentao: onStartCommand
03-15 15:10:31.684 16383-16525/yuzhentao.servicedemo E/yuzhentao: 1
03-15 15:10:32.684 16383-16525/yuzhentao.servicedemo E/yuzhentao: 2
03-15 15:10:33.684 16383-16525/yuzhentao.servicedemo E/yuzhentao: 3
03-15 15:10:34.684 16383-16525/yuzhentao.servicedemo E/yuzhentao: 4
03-15 15:10:35.684 16383-16525/yuzhentao.servicedemo E/yuzhentao: 5
03-15 15:10:36.349 16383-16383/yuzhentao.servicedemo E/yuzhentao: onDestroy
第二种情况是绑定服务和解绑服务:
03-15 15:24:40.795 28940-28940/yuzhentao.servicedemo E/yuzhentao: onCreate
03-15 15:24:40.796 28940-28940/yuzhentao.servicedemo E/yuzhentao: onBind
03-15 15:24:41.796 28940-29028/yuzhentao.servicedemo E/yuzhentao: 1
03-15 15:24:42.797 28940-29028/yuzhentao.servicedemo E/yuzhentao: 2
03-15 15:24:43.796 28940-29028/yuzhentao.servicedemo E/yuzhentao: 3
03-15 15:24:44.796 28940-29028/yuzhentao.servicedemo E/yuzhentao: 4
03-15 15:24:45.796 28940-29028/yuzhentao.servicedemo E/yuzhentao: 5
03-15 15:24:46.579 28940-28940/yuzhentao.servicedemo E/yuzhentao: onUnbind
03-15 15:24:46.579 28940-28940/yuzhentao.servicedemo E/yuzhentao: onDestroy
第三种情况是开始服务,绑定服务和解绑服务,因为此时点停止服务没有卵用,先必须解绑服务才行,可以看到绑定服务一定会走onBind()
03-15 15:27:42.177 31648-31648/yuzhentao.servicedemo E/yuzhentao: onCreate
03-15 15:27:42.178 31648-31648/yuzhentao.servicedemo E/yuzhentao: onStartCommand
03-15 15:27:43.177 31648-31740/yuzhentao.servicedemo E/yuzhentao: 1
03-15 15:27:44.177 31648-31740/yuzhentao.servicedemo E/yuzhentao: 2
03-15 15:27:44.955 31648-31648/yuzhentao.servicedemo E/yuzhentao: onBind
03-15 15:27:45.177 31648-31740/yuzhentao.servicedemo E/yuzhentao: 3
03-15 15:27:46.177 31648-31740/yuzhentao.servicedemo E/yuzhentao: 4
03-15 15:27:47.178 31648-31740/yuzhentao.servicedemo E/yuzhentao: 5
03-15 15:27:48.178 31648-31740/yuzhentao.servicedemo E/yuzhentao: 6
03-15 15:27:49.178 31648-31740/yuzhentao.servicedemo E/yuzhentao: 7
03-15 15:27:50.179 31648-31740/yuzhentao.servicedemo E/yuzhentao: 8
03-15 15:27:51.178 31648-31740/yuzhentao.servicedemo E/yuzhentao: 9
03-15 15:27:52.178 31648-31740/yuzhentao.servicedemo E/yuzhentao: 10
03-15 15:27:53.178 31648-31740/yuzhentao.servicedemo E/yuzhentao: 11
03-15 15:27:53.523 31648-31648/yuzhentao.servicedemo E/yuzhentao: onUnbind
03-15 15:27:53.523 31648-31648/yuzhentao.servicedemo E/yuzhentao: onDestroy
第四种情况是绑定服务,开始服务和解绑服务,因为此时...
03-15 15:28:13.886 32238-32238/yuzhentao.servicedemo E/yuzhentao: onCreate
03-15 15:28:13.887 32238-32238/yuzhentao.servicedemo E/yuzhentao: onBind
03-15 15:28:14.888 32238-32316/yuzhentao.servicedemo E/yuzhentao: 1
03-15 15:28:15.888 32238-32316/yuzhentao.servicedemo E/yuzhentao: 2
03-15 15:28:16.613 32238-32238/yuzhentao.servicedemo E/yuzhentao: onStartCommand
03-15 15:28:16.888 32238-32316/yuzhentao.servicedemo E/yuzhentao: 3
03-15 15:28:17.888 32238-32316/yuzhentao.servicedemo E/yuzhentao: 4
03-15 15:28:18.888 32238-32316/yuzhentao.servicedemo E/yuzhentao: 5
03-15 15:28:19.889 32238-32316/yuzhentao.servicedemo E/yuzhentao: 6
03-15 15:28:20.889 32238-32316/yuzhentao.servicedemo E/yuzhentao: 7
03-15 15:28:21.889 32238-32316/yuzhentao.servicedemo E/yuzhentao: 8
03-15 15:28:22.737 32238-32238/yuzhentao.servicedemo E/yuzhentao: onUnbind
03-15 15:28:22.738 32238-32238/yuzhentao.servicedemo E/yuzhentao: onDestroy
第五种情况是开始服务和解绑服务,报错,因为并没有绑定服务
第六种情况是开始服务和获取数字,报错,因为并没有绑定服务,不能进行通信
第七种情况就是绑定服务,获取数字和解绑服务,其中那个3'就是调用Service中的方法来获取的
03-15 15:28:45.824 353-353/yuzhentao.servicedemo E/yuzhentao: onCreate
03-15 15:28:45.824 353-353/yuzhentao.servicedemo E/yuzhentao: onBind
03-15 15:28:46.824 353-461/yuzhentao.servicedemo E/yuzhentao: 1
03-15 15:28:47.824 353-461/yuzhentao.servicedemo E/yuzhentao: 2
03-15 15:28:48.824 353-461/yuzhentao.servicedemo E/yuzhentao: 3
03-15 15:28:49.694 353-353/yuzhentao.servicedemo E/yuzhentao: 3'
03-15 15:28:49.824 353-461/yuzhentao.servicedemo E/yuzhentao: 4
03-15 15:28:50.825 353-461/yuzhentao.servicedemo E/yuzhentao: 5
03-15 15:28:51.825 353-461/yuzhentao.servicedemo E/yuzhentao: 6
03-15 15:28:52.825 353-461/yuzhentao.servicedemo E/yuzhentao: 7
03-15 15:28:53.773 353-353/yuzhentao.servicedemo E/yuzhentao: onUnbind
03-15 15:28:53.773 353-353/yuzhentao.servicedemo E/yuzhentao: onDestroy
总结一下就是绑定的服务,只能通过解绑来停止,只有绑定的服务,才能进行通信,也就是可以通过Service来获取信息,而开始服务,只要调用停止服务就能停止,前提是开始服务之后并没有绑定服务。
最后是效果图:
Demo地址:http://download.csdn.net/detail/qq_23940659/9467044