1.为啥需要它?
Service(服务)是一个可以在后台执行长时间运行操作而没有用户界面的应用组件。属于计算型组件。
组件Service必须要吗?
我们可以使用Thread替代Service吗?
理由:
1.Service可以通过Binder进行进程间通信,Thread不行。
2.Thread容易被杀。进程的优先级分为五种,分别是:前台进程,可见进程,服务进程,后台进程,空进程。当我们运行长时间后台任务时,Thread是存在于后台进程的,而Service是存在服务进程,Service比Thread所处的进程优先级高,不容易被杀。
2.怎样使用它?
- 继承IntentService
public class MyIntentService extends IntentService {
public MyIntentService() {
super("hyh");
}
@Override
protected void onHandleIntent(@Nullable Intent intent) {
int msg = intent.getIntExtra("msg",0);
int count=0;
while (true){
Log.i("androidLog","msg.what="+msg+";count="+count);
count++;
if(count>100){
break;
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
- 继承Service类
public class MyService extends Service {
private ServiceHandler serviceHandler;
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
class ServiceHandler extends Handler{
int count =0;
public ServiceHandler(Looper looper){
super(looper);
}
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
while (true){
Log.i("androidLog","msg.what="+msg.what+";count="+count);
count++;
if(count>100){
break;
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
stopSelf();
}
}
@Override
public void onCreate() {
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
int msg = intent.getIntExtra("msg",0);
HandlerThread thread = new HandlerThread(""+msg, Process.THREAD_PRIORITY_BACKGROUND);
thread.start();
serviceHandler = new ServiceHandler(thread.getLooper());
serviceHandler.sendEmptyMessageAtTime(msg,1000);
return START_STICKY;
}
}
- 创建Bound Service
继承Binder类(进程内通信)
public class MyBoundService extends Service {
LocalBinder localBinder;
@Nullable
@Override
public IBinder onBind(Intent intent) {
localBinder = new LocalBinder();
return localBinder;
}
public class LocalBinder extends Binder{
MyBoundService getService(){
return MyBoundService.this;
}
}
public int getRandomNumber(){
return new Random().nextInt(10);
}
}
3.附加知识有哪些?
1.生命周期方法具体介绍
1.1 startService()
- 作用:启动Service服务
- 手动调用startService()后,自动调用内部方法:onCreate()、onStartCommand()
- 调用逻辑如下:
1.2 stopService()
- 作用:关闭Service服务
- 手动调用stopService()后,自动调用内部方法:onDestory()
- 调用的逻辑
1.3 bindService()
- 作用:绑定Service服务
- 手动调用bindService()后,自动调用内部方法:onCreate()、onBind()
- 调用的逻辑:
1.4 unbindService()
- 作用:解绑Service服务
- 手动调用unbindService()后,自动调用内部方法:onCreate()、onBind()、onDestory()
- 调用的逻辑:
2. 常见的生命周期使用
2.1 只使用startService启动服务的生命周期
2.2 只使用BindService绑定服务的生命周期
2.3 同时使用startService()启动服务、BindService()绑定服务的生命周期
服务进程通信是采用Binder方式,进程间通信,我们可以采用Bundle,文件,ContentProvider,Messenger,AIDL,Socket方式,但是Bundle传输的对象必须实现序列化,所以有些Bundle不支持的类型我们无法通过Bundle传输。采用文件共享方式,linux系统支持并发写,所以在多个进程间采用文件进行通信并不可靠,而ContentProvider,Messenger和AIDL底层都是采用Binder方式实现的,采用Socket网络方式进行进程间通信,消耗资源大,而且UI线程不支持网络通信。
注意事项
- 同一个Activity或者不同Activity,startService多次,除第一次调用onCreate()、onStartCommand()外,其余只会调用onStartCommand().
- 只要有一个Activity调用stopService(),服务就会调用onDestroy()停止。
- 同一个Activity或者不同Actvity,bindService多次,只会第一次调用一次onCreate()、onBind().
- 需要所有绑定的Activty调用unBindService()或者Activity关闭(自动解绑),服务才会调用onDestroy()停止。