从使用方法上探索Service:
首先创建一个简单的demo来看看service的生命周期:
第一次启动Service:
多次启动同一个Service:
发现只有onStartCommand这个方法执行了。
第一次停止Service,接下来停止就没有反应了。重新执行会重新调用onCreate的方法。
好了,对于服务的启动,可以看到他的生命周期为:
对于服务的绑定,可以看到他的生命周期为:
注意到使用onbind()只是绑定,不能使服务在后台运行起来。只有startService才能使服务在后台运行起来。 如果服务是通过启动服务(startService)来开始的话,就只能通过stopService()来进行销毁。如果服务一开始是通过bindService()来创建服务的话,只能通过unbindService()来进行销毁。可以说是成对出现了哈哈哈哈。
(依次调用startService,bindService,unbindService)
(依次调用bindService,unbindService)
注意到bindService()方法中有个参数BIND_AUTO_CREATE,这个参数会让服务绑定的时候,如果服务不存在,就会自动创建服务,此时的生命周期为:onCreate->onBind->onUnbind->onDestory(此时服务不在后台运行,并且他会随着活动的销毁而被销毁,(这个和服务的启动生命周期不一样,毕竟是绑过的嘛要死一起死哈哈哈)。如果调用这个onbind方法的时候,服务已经存在了,那么bindService只能使onBind方法被调用,而unbindService只能使onUnbind方法被调用。
绑定服务实现监控主要是在onbind()方法中实现:
我们来写一个有意思的demo:就是在服务中实现1-100的遍历,主活动获取到当前i的信息:
服务中遍历的代码:(我把它写在onCreate()方法中)
@Override
public void onCreate() {
Log.d("MyService","onCreate executed");
super.onCreate();
new Thread(){
@Override
public void run() {
super.run();
for(i=0;i<100;i++)
{
try {
sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
}
这个线程会在服务中从1遍历到100.
然后编写onbind()方法:
@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
Log.d("MyService","onBind executed");
return new MyBinder();
}
//对于onBind方法而言,要求返回IBinder对象,我们定义一个内部类,集成Binder类
class MyBinder extends Binder{
//实现进度监控
public int getProcess(){
return i;
}
}
注意到这里返回一个IBinder对象,但是IBinder阅读源码会发现他是一个接口类,定义一个类继承IBinder要重写一堆方法,而Binder实现了IBinder接口,所以直接继承Binder就简单很多。
这里返回的IBinder对象会作为参数传入onServiceConnected()方法中,这里注意类型转换:
private ServiceConnection conn=new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
MyService.MyBinder mb=(MyService.MyBinder)service;
int step=mb.getProcess();//取得服务的进度
Log.e("MainActivity","当前的i是"+step);
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
这样绑定+监控就设置好了,启动绑定服务的方法是
case R.id.bind_service: Intent bindintent=new Intent(this,MyService.class); bindService(bindintent, conn,BIND_AUTO_CREATE); break;
传入的第二个参数conn就是ServiceConnection类的一个对象。
完成后可以看到
蛮有意思的对不对??
源码也在评论区。
现在更进一步探索service的工作过程(源码上):
这里的内容下周更新~
图片来源:https://blog.csdn.net/weixin_38196407/article/details/89491156