服务(Service)是Android四大组件之一。可以实现Android程序后台运行。适用于去执行那些不需要和用户交互而且还要求长期后台运行的任务。
Service默认运行在主线程,不可做耗时操作(15s ANR)。所以要在Service中做耗时操作需要开线程。
Service的开启服务有两种方式,启动式服务和绑定式服务。绑定式服务可以返回一个代理对象IBinder。所以可以调用Service中的方法和属性等等。即绑定者(一般是Activity)可以和服务有一定的交互。而启动式服务不可以。
下面讲述Service的详细使用。
<1> 开启服务
Intent startIntent=new Intent(this, MyService.class);
startService(startIntent);
<2> 停止服务
Intent stopIntent=new Intent(this, MyService.class);
stopService(stopIntent);
<3> 生命周期
onCreate()->onStartCommand()(服务第一次执行)
onStartCommand()(服务不是第一次执行)
onBind()方法不执行
<4> 总结
使用startService()方法(启动式方式)启用服务,启动者与服务之间没有关连,所以不能完成交互。但是如果启动者退出了,服务仍然运行(只要不执行stopService(stopIntent)方法)。
<5> Demo
(1) 服务
package com.wjn.lubandemo.component;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;
public class MyService extends Service {
public MyService() {
}
@Override
public void onCreate() {
super.onCreate();
Log.d("MyService", "onCreate方法执行");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
String value = intent.getStringExtra("value");
Log.d("MyService", "onStartCommand方法执行value----:" + value);
//模拟耗时操作
new Thread() {
@Override
public void run() {
super.run();
for (int i = 0; i < 10; i++) {
Log.d("MyService", "onStartCommand方法模拟耗时操作i----:" + i);
}
}
}.start();
return super.onStartCommand(intent, flags, startId);
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onDestroy() {
super.onDestroy();
Log.d("MyService", "onDestroy方法执行");
}
}
(2) 注册
(3) 开启服务
Intent startIntent=new Intent(ServiceActivity.this, MyService.class);
startIntent.putExtra("value","启动式***开启服务传值");
startService(startIntent);
(4) 停止服务
Intent stopIntent=new Intent(ServiceActivity.this, MyService.class);
stopIntent.putExtra("value","启动式***停止服务传值");
stopService(stopIntent);
(5) 结果
第一次开启服务 onCreate()->onStartCommand()
D/MyService: onCreate方法执行
D/MyService: onStartCommand方法执行value----:启动式***开启服务传值
D/MyService: onStartCommand方法模拟耗时操作i----:0
D/MyService: onStartCommand方法模拟耗时操作i----:1
D/MyService: onStartCommand方法模拟耗时操作i----:2
D/MyService: onStartCommand方法模拟耗时操作i----:3
D/MyService: onStartCommand方法模拟耗时操作i----:4
D/MyService: onStartCommand方法模拟耗时操作i----:5
D/MyService: onStartCommand方法模拟耗时操作i----:6
D/MyService: onStartCommand方法模拟耗时操作i----:7
D/MyService: onStartCommand方法模拟耗时操作i----:8
D/MyService: onStartCommand方法模拟耗时操作i----:9
第二次开启服务 onStartCommand()
D/MyService: onStartCommand方法执行value----:启动式***开启服务传值
D/MyService: onStartCommand方法模拟耗时操作i----:0
D/MyService: onStartCommand方法模拟耗时操作i----:1
D/MyService: onStartCommand方法模拟耗时操作i----:2
D/MyService: onStartCommand方法模拟耗时操作i----:3
D/MyService: onStartCommand方法模拟耗时操作i----:4
D/MyService: onStartCommand方法模拟耗时操作i----:5
D/MyService: onStartCommand方法模拟耗时操作i----:6
D/MyService: onStartCommand方法模拟耗时操作i----:7
D/MyService: onStartCommand方法模拟耗时操作i----:8
D/MyService: onStartCommand方法模拟耗时操作i----:9
第三次开启服务 onStartCommand()
...
停止服务 onDestroy()
D/MyService: onDestroy方法执行
<1> 绑定服务
Intent bindIntent=new Intent(this, MyService.class);
bindService(bindIntent, conn, BIND_AUTO_CREATE);
<2> 解绑服务
unbindService(conn);
注意:
只有调用过bindService()方法才可以调用unBindService() 这两个方法必须一一对应,可以只调用前者,但是绝对不能再未调用前者的情况下,调用后者,或者多次调用后者。
<3> 生命周期
onCreate()->onBind()(服务第一次执行)
onBind()(服务不是第一次执行)
onStartCommand()方法不执行
<4> 总结
使用bindService()方法启用服务,调用者与服务绑定在了一起,调用者一旦退出,服务也就终止,大有“不求同时生,必须同时死”的 特点。但是可以完成绑定者与服务的交互。
<5> Demo
(1) 服务
package com.wjn.lubandemo.component;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;
public class MyService extends Service {
public MyService() {
}
@Override
public void onCreate() {
super.onCreate();
Log.d("MyService", "onCreate方法执行");
}
@Override
public IBinder onBind(Intent intent) {
Log.d("MyService", "onBind方法执行");
return new MyBinder();
}
@Override
public boolean onUnbind(Intent intent) {
Log.d("MyService", "onUnbind方法执行");
return super.onUnbind(intent);
}
@Override
public void onDestroy() {
super.onDestroy();
Log.d("MyService", "onDestroy方法执行");
}
/**
* 代理类
*/
class MyBinder extends Binder {
public String testMethod1() {
return "绑定的服务返回给调用者的回调";
}
public int testMethod2() {
return 20;
}
public void testMethod3() {
Log.d("MyService", "绑定者调用了服务的testMethod3()方法");
}
}
}
(2) 注册
(3) 绑定服务 解绑服务
package com.wjn.lubandemo.component;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import com.wjn.lubandemo.R;
public class ServiceActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_service);
TextView textView3 = findViewById(R.id.activity_service_textview3);
textView3.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent bindIntent = new Intent(ServiceActivity.this, MyService.class);
bindIntent.putExtra("value", "绑定式***开始服务传值");
bindService(bindIntent, MyServiceConnection, BIND_AUTO_CREATE);
}
});
TextView textView4 = findViewById(R.id.activity_service_textview4);
textView4.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
unbindService(MyServiceConnection);
}
});
}
/**
* ServiceConnection 接口实现类
*/
ServiceConnection MyServiceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
//获取绑定式服务的代理类
MyService.MyBinder binder = (MyService.MyBinder) service;
//调用绑定式服务的各种方法
String s = binder.testMethod1();
int n = binder.testMethod2();
binder.testMethod3();
Log.d("MyService", "onServiceConnected方法name----:" + name);
Log.d("MyService", "绑定者获取服务的s----:" + s);
Log.d("MyService", "绑定者获取服务的n----:" + n);
}
@Override
public void onServiceDisconnected(ComponentName name) {
Log.d("MyService", "onServiceDisconnected方法name----:" + name);
}
};
}
说明:
参数3:int flags
参数 flags的值有如下情况:
(1) public static final int BIND_AUTO_CREATE
表明只要绑定存在,就自动建立 Service。同时也告知Android系统这个Service的重要程度与调用者相同, 除非考虑终止调用者,否则不要关闭这个Service。
(2) public static final int BIND_DEBUG_UNBIND
(3) public static final int BIND_NOT_FOREGROUND
(4) public static final int BIND_ABOVE_CLIENT
(5) public static final int BIND_WAIVE_PRIORITY
一般使用第一个即可。
(4) 结果
绑定
D/MyService: onCreate方法执行
D/MyService: onBind方法执行
D/MyService: 绑定者调用了服务的testMethod3()方法
D/MyService: onServiceConnected方法name----:ComponentInfo{com.wjn.lubandemo/com.wjn.lubandemo.component.MyService}
D/MyService: 绑定者获取服务的s----:绑定的服务返回给调用者的回调
D/MyService: 绑定者获取服务的n----:20
解绑
D/MyService: onUnbind方法执行
D/MyService: onDestroy方法执行
上述可知
启动式服务(前台服务)启动者退出后服务还会运行(不手动停止的情况下),这是它的优点。但是启动者不能与服务进行交互,这是它的弱点。
绑定式服务(后台服务)绑定者退出服务就会停止,或者后台服务优先级比较低,当内存不足时容易被系统回收,这是它的弱点。但是绑定者可以和服务交互,这是它的优点。
所以使用服务时一般混合使用。