三十、Android Service介绍
Service是Android四大组件中与Activity最相似的组件,它们都代表可执行的程序,Service与Activity的区别在于: Service一直在后台运行,它没有用户界面,所以绝不会到前台来。一旦Service被启动起来之后,它就与 Activity一样。它完全具有自己的生命周期。关于程序中Activity与 Service的选择标准是:如果某个程序组件需要在运行时向用户呈现某种界面,或者该程序需要与用户交互,就需要使用 Activity,否则就应该考虑使用 Service了。
开发者开发Service的步骤与开发Aciy的步骤很像,开发Service组件需要先开发个Service的子类,然后在Androidmanifest.xml文件中配置该 Service,配置时可通过<Intent- filter.../>元素指定它可被哪些Intent启动。
Android系统本身提供了大量的 Service组件,开发者可通过这些系统 Service来操作Android系统本身。
开发Service两个步骤:
定义一个继承Service的子类;
在Androidmanifest.xml文件中配置该Service
public class FirstService extends Service {
/*
* 该方法是Service子类必须实现的方法。
* 该方法返回一个IBinder对象,应用程序
* 可通过该对象与Service组件通信。
*/
@Override
public IBinder onBind(Intent intent) {
return null;
}
//当该Service第一次被创建时回调该方法
@Override
public void onCreate() {
super.onCreate();
System.out.println("Service is Created");
}
//每次客户端调用startService(Intent)方法启动该Service时都会调用
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
System.out.println("Service is Started");
return START_STICKY;
}
//当该Service上绑定的所有客户端都断开连接时将会回调该方法
@Override
public boolean onUnbind(Intent intent) {
return super.onUnbind(intent);
}
//Service被关闭之前回调
@Override
public void onDestroy() {
super.onDestroy();
System.out.println("Service is Destroyed");
}
}
配置Service 使用<service.../>。与配置Activity相似,配置Service时也可为<service.../>元素配置<intent-filter.../>,用于说明该Service可被哪些Intent启动。
<service android:name=".service.FirstService">
<intent-filter>
<action android:name="com.myandroid.service.FIRST_SERVICE"/>
</intent-filter>
</service>
当该 Service开发完成之后,接下来就可在程序中运行该 Service了, Android系统中运行 Service有如下两种方式:
1.通过 Context 的 startservice()方法:通过该方法启用 Service,访问者与 Service
之间没有关联,即使访问者退出了, Service仍然运行。
2.通过 Context 的 bondservice0方法:使用该方法启用 Service,访问者与 Service
绑定在了一起,访问者一且退出, Service也就终止下面先示范的第一种方式运行 Service。
启动停止Service
public class Activity25 extends BaseActivity implements View.OnClickListener {
public Intent intent;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity25);
Button start = findViewById(R.id.start);
Button stop = findViewById(R.id.stop);
/*
* 服务意图必须是显性声明。 这是为了防止造成冲突(有多个Service用同样的intent-filter的情况)
* 这是Android 5.0 (Lollipop) 之后的规定。不能用包名的方式定义Service Intent, 而要用显
* 性声明:new Intent(context, xxxService.class);
*
* 如果想继续使用隐式意图的话,加上包名信息即可
*/
intent = new Intent();
intent.setAction("com.myandroid.service.FIRST_SERVICE");
intent.setPackage(context.getPackageName());//兼容Android 5.0
start.setOnClickListener(this);
stop.setOnClickListener(this);
}
@Override
public void onClick(View view) {
switch (view.getId()){
case R.id.start:
startService(intent);
break;
case R.id.stop:
stopService(intent);
break;
}
}
}
绑定本地Service并与之通信
当程序通过 startservice()和 stopservice()启动、关闭 Service时, Service与访问者之间基本上不存在太多的关联,因此 Service和访问者之间也无法进行通信、数据交换。
如果Service和访问者之间需要进行方法调用或数据交换,则应该使用bindService()和unbindService()方法启动、关闭服务。
Context的bindService()方法的完整方法签名为: bindService(Intent service,Serviceconnection conn. int flags)该方法的三个参数的解释如下:
service:该参数通过Intent指定要启动的Service
con:该参数是一个ServiceConnection对象,该对象用于监听访问者与Service
之间的连接情况。当访问者与Service之间连接成功时将回调该Serviceconnection对象的onServiceConnected(ComponentName name, IBinder service)方法;当访问者与Service之间断开连接时将回调该ServiceConnection对象的onServiceDisconnected(ComponentName name)方法。
flags:指定绑定时是否自动创建Service(如果Service还未创建)。该参数可指定为0(不自动创建)或BIND_AUTO_ CREATE(自动创建)。
public class BindService extends Service {
private int count;
private boolean quit;
//定义onBinder方法的返回的对象
private MyBinder binder = new MyBinder();
//通过继承Binder来实现IBinder类
public class MyBinder extends Binder{
public int getCount(){
//获取Service的运行状态:count
return count;
}
}
//必须实现的方法
@Override
public IBinder onBind(Intent intent) {
System.out.println("Service is Binded");
//返回IBinder对象
return binder;
}
//Service被创建时回调该方法
@Override
public void onCreate() {
super.onCreate();
System.out.println("Service is Created");
//启动一条线程、动态地修改count状态值
new Thread(){
@Override
public void run() {
super.run();
while (!quit){
try{
Thread.sleep(1000);
}catch (Exception e){
e.printStackTrace();
}
count++;
}
}
}.start();
}
//Service被断开连接时回调该方法
@Override
public boolean onUnbind(Intent intent) {
System.out.println("Service is Unbinded");
return true;
}
//Service被关闭之前回调
@Override
public void onDestroy() {
super.onDestroy();
this.quit = true;
System.out.println("Service is Destroyed");
}
}
定义Activity来绑定Service。
public class Activity26 extends BaseActivity {
Button bind, unbind, getServiceStatus;
//保存所启动的Service的IBinder对象
BindService.MyBinder binder;
//定义一个ServiceConnection对象
private ServiceConnection conn = new ServiceConnection() {
//当该Activity与Service连接成功时回调该方法
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
System.out.println("--Service Connected--");
//获取Service的onBind方法返回的MyBinder对象
binder = (BindService.MyBinder) iBinder;
}
//当该Activity与Service断开连接时回调该方法
@Override
public void onServiceDisconnected(ComponentName componentName) {
System.out.println("--Service Disconnected--");
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity26);
bind = findViewById(R.id.bind);
unbind = findViewById(R.id.unbind);
getServiceStatus = findViewById(R.id.getServiceStatus);
final Intent intent = new Intent(context, BindService.class);
bind.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//绑定指定Service
bindService(intent, conn, Service.BIND_AUTO_CREATE);
}
});
unbind.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//解绑Service
unbindService(conn);
}
});
getServiceStatus.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//获取并显示Service的count值
Toast.makeText(context, "Service的count值为:" + binder.getCount(), Toast.LENGTH_SHORT).show();
}
});
}
}
Service生命周期
两种启动方式Service生命周期如下图:
通过startService()方法启动Service的生命周期 通过bindService()启动的Service的生命周期