Service介绍
Service是Android的四大组件之一,和Activity最大的区别是没有界面,是一个跑在后台的服务。
Service的两种启动方式:
startService启动,生命周期:
onCreate()——>onStartCommand()——>onDestroy()
bindService启动,生命周期:
onCreate()——>onBind()——>onUnbind()——>onDestroy()
Service启动方式
-
startService启动
使用这种方式开启的服务,服务开启后就和调用者没有任何关系了,之后调用者的生死不会影响服务的运行。调用者也不能用服务进行交互
首次调用startService会依次调用onCreate()——>onStartCommand()
服务启动后多次调用startService则只会多次回调onStartCommand()方法,onCreate()只会在启动是调用一次
当服务需要退出时,需要调用stopService(可多次调用)或者调用服务内部的stopSelf,这时会回调onDestroy()方法 -
bindService启动
使用这种方式绑定的服务,服务的生死就和调用者的生死绑定到一起了,调用者销毁后,服务也会销毁但这种方式调用者可以
和服务进行交互
首次调用bindService会依次调用onCreate()——>onBind() ——>onServiceConnected()方法
服务启动后多次调用bindService不会回调任何方法,即onCreate()和onBind()都只被调用一次
当调用unbindService或调用者退出时,服务退出,则会回调onUnbind()——>onDestroy()
注意:多次调用unbindService,抛出java.lang.IllegalArgumentException: Service not registered
混合模式
先开启服务再绑定服务 或 先绑定服务再开启服务
使用这种方式开启服务后,需要调用unbindService解绑服务、stopService停止服务,也可以先调用stopService再调用unbindService顺序不分先后,但都要调用。
如果直接退出调用者,这时相当于只调用了unbindService,此时Service只会回调onUnbind()方法,服务依然还在后台运行此时等同于startService方式启动了服务,直到调用了stopService或内存不足时才停止服务。
说明:Android系统仅会为一个Service创建一个实例对象,所以不管是启动服务还是绑定服务,操作都是同一个Service实例
Service使用
1、创建Service子类
public class TestService extends Service {
@Override
public void onCreate() {
super.onCreate();
Log.d("TestService:", "onCreate");
}
/*
* 过时了推荐使用onStartCommand
* */
@Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
String value = intent.getStringExtra("twoActivity");
Log.d("TestService:", "onStartCommand:" + value);
return super.onStartCommand(intent, flags, startId);
}
@Override
public boolean onUnbind(Intent intent) {
String value = intent.getStringExtra("twoActivity");
Log.d("TestService:", "onUnbind:" + value);
return super.onUnbind(intent);
}
@Override
public void onDestroy() {
super.onDestroy();
Log.d("TestService:", "onDestroy");
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
String value = intent.getStringExtra("twoActivity");
Log.d("TestService:", "onBind:" + value);
//返回一个Binder对象
return new MyBinder();
}
/**
* 通过onBind方法把MyBinder对象返回给Activity,
* 用于数据交换
*/
public class MyBinder extends Binder {
//提供一个方法给Activity调用
public TestService1 getService() {
// 返回TestService对象,这样就可以让Activity调用Service的公共方法了
return TestService1.this;
}
}
/**
* 与Activity交互的接口
*/
public String getMyName() {
return "liuyunzhao";
}
}
- 定义一个Service子类
- 在TestService类中创建一个MyBinder的内部类并继承Binder,并添加一个返回TestService对象的方法,用于和Activity进行交互
- 在onBind方法中返回一个MyBinder对象
说明:onStartCommand返回的是int值,一共有四个返回值,分别是:
START_STICKY:如果service因内存不足被系统kill掉,一段时间后内存再次空闲时,系统将尝试重新创建此Service,一旦创建成功后将回调onStartCommand方法,如果在此期间没有任何启动命令被传递到service,那么参数Intent将为null
START_NOT_STICKY:使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统不会自动重启该服务
START_REDELIVER_INTENT:使用这个返回值时,会重传Intent。如果在执行完onStartCommand后,服务被异常kill掉,系统会自动重启该服务,并将Intent的值传入
START_STICKY_COMPATIBILITY:START_STICKY的兼容版本,但不保证服务被kill后一定能重启
2、创建Activity子类
首先在Activity中创建服务的连接对象ServiceConnection,用于与Service交互
private TestService mBindService; //绑定的Service对象
/**
* 服务连接对象
*/
private ServiceConnection connection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.d("TestService:","onServiceConnected");
TestService.MyBinder binder = (TestService.MyBinder) service;
//拿到绑定的Service对象
mBindService = binder.getService();
String myName = mBindService.getMyName();
Log.d("TestService:","myName="+myName);
}
@Override
public void onServiceDisconnected(ComponentName name) {
Log.d("TestService:","onServiceDisconnected");
mBindService = null;
}
};
onServiceConnected():绑定服务成功时被回调,通过这个方法可获取到从Service传递过来的IBinder对象,通过IBinder对象,可实现Activity与Service的交互
onServiceDisconnected():Service服务被杀死或意外崩溃时回调,如内存资源不足
注意:当客户端取消绑定时,系统不会调用该方法
2.1 多次调用startService
private void btn1Click() {
Intent intent = new Intent(this, TestService.class);
intent.putExtra("twoActivity", "startServiceData");
startService(intent);
startService(intent);
startService(intent);
}
打印结果如下:
com.cn.liuyz.servicedemo D/TestService:: onCreate
com.cn.liuyz.servicedemo D/TestService:: onStartCommand:startServiceData
com.cn.liuyz.servicedemo D/TestService:: onStartCommand:startServiceData
com.cn.liuyz.servicedemo D/TestService:: onStartCommand:startServiceData
2.2 调用stopService
private void btn2Click() {
Intent intent = new Intent(this, TestService.class);
stopService(intent);
}
打印结果如下:
com.cn.liuyz.servicedemo D/TestService:: onDestroy
2.3 多次调用bindService
private void btn3Click() {
Intent intent = new Intent(this, TestService.class);
intent.putExtra("twoActivity", "bindServiceData");
/*
* 第一个参数是intent对象,表示开启服务
* 第二个参数是绑定服务连接
* 第三个参数是绑定时是否自动创建Service,BIND_AUTO_CREATE代表自动创建
* */
bindService(intent, connection, Context.BIND_AUTO_CREATE);
bindService(intent, connection, Context.BIND_AUTO_CREATE);
bindService(intent, connection, Context.BIND_AUTO_CREATE);
}
打印结果如下:
com.cn.liuyz.servicedemo D/TestService:: onCreate
com.cn.liuyz.servicedemo D/TestService:: onBind:bindServiceData
com.cn.liuyz.servicedemo D/TestService:: onServiceConnected
com.cn.liuyz.servicedemo D/TestService:: myName=liuyunzhao
2.4 调用unbindService(不可多次调用)
private void btn4Click() {
unbindService(connection);
}
打印结果如下:
com.cn.liuyz.servicedemo D/TestService:: onUnbind:bindServiceData
com.cn.liuyz.servicedemo D/TestService:: onDestroy
2.5 先开启再绑定Service
打印结果如下:
com.cn.liuyz.servicedemo D/TestService:: onCreate
com.cn.liuyz.servicedemo D/TestService:: onStartCommand:bindServiceData
com.cn.liuyz.servicedemo D/TestService:: onStartCommand:bindServiceData
com.cn.liuyz.servicedemo D/TestService:: onStartCommand:bindServiceData
com.cn.liuyz.servicedemo D/TestService:: onBind:bindServiceData
com.cn.liuyz.servicedemo D/TestService:: onServiceConnected
com.cn.liuyz.servicedemo D/TestService:: myName=liuyunzhao
2.6 先解绑再停止服务
打印结果如下:
com.cn.liuyz.servicedemo D/TestService:: onUnbind:bindServiceData
com.cn.liuyz.servicedemo D/TestService:: onDestroy
2.7 先绑定再开启Service
打印结果如下:
com.cn.liuyz.servicedemo D/TestService:: onCreate
com.cn.liuyz.servicedemo D/TestService:: onBind:bindServiceData
com.cn.liuyz.servicedemo D/TestService:: onServiceConnected
com.cn.liuyz.servicedemo D/TestService:: myName=liuyunzhao
com.cn.liuyz.servicedemo D/TestService:: onStartCommand:startServiceData
com.cn.liuyz.servicedemo D/TestService:: onStartCommand:startServiceData
com.cn.liuyz.servicedemo D/TestService:: onStartCommand:startServiceData
2.8 先解绑再停止服务
打印结果如下:
com.cn.liuyz.servicedemo D/TestService:: onUnbind:bindServiceData
com.cn.liuyz.servicedemo D/TestService:: onDestroy