(一)、Service 简介:
Service即“服务”的意思,在android中Service运行在后台,它是不可见的并且没有界面。Service可以在很多场合中用到,比如播放音频,后台定位用户位置等等。
1、Service运行在后台,不可交互。
2、Service运行在主线程,它不会创建子线程,除非另有规定否则它和应用程序运行在同一进程。
3、Service主要用来执行耗时操作,如上传/下载文件,播放音乐等
(二)Service和后台线程相比,优势是什么?
1、Service可以放在独立的进程中,所以更安全;
2、使用Service可以依赖现有的binder机制,不需要在应用层面上处理线程同步的繁杂工作;
3、系统可以重新启动异常死去的Service。
(三)服务分类与生命周期
1、本地服务Local Service:Local Service 用于应用程序内部
启动服务的方法:
1)、Context.startService()
启动后与调用者无关,即使调用者退出,服务仍然在后台运行。调用者可以调用stopService(Intent serviceIntent)方法结束Service,或者在Service内部调用stopSelf(...)
生命周期:a、服务没有启动:onCreate():创建服务-->onStartCommand():服务开始运行-->onDeatory():服务被停
b.服务已经启动:onStartCommand()-->onDeatory()
说明:
①在程序中调用:context.startService() 会触发执行Service生命周期中的onCreate()、onStartCommand()回调方法,此时服务就开始正式运行;
②如果Service还没有运行,则android先调用onCreate()然后调用onStartCommand();如果Service已经运行,则只调用onStartCommand(),所以一个Service的onStartCommand方法可能会重复调用多次;
③如果在程序中调用:context.stopService()会触发执行Service生命周期中的onDestroy()回调方法,会让服务停止;
④stopService()的时候直接onDestroy,如果是调用者自己直接退出而没有调用stopService()的话,Service会一直在后台运行。该Service的调用者再启动该Service后可以通过stopService关闭Service;stopSelf()
⑤所以StartService的生命周期为:onCreate --> onStartCommand(可多次调用) --> onDestroy。
onStartCommand()有三个返回值
①START_STICKY(常量:1):sticky的意思是“粘性的”。如果服务被异常kill掉,系统会自动重启该服务。当再次启动服务时,传入的第一个参数将为null;
② START_NOT_STICKY(常量:2):“非粘性的”。服务被异常kill掉后系统不会重启服务
③ START_REDELIVER_INTENT(常量:3):重传Intent。使用这个返回值时,如果服务被异常kill掉,系统会自动重启该服务,并将Intent的值传入。
2)、Context.bindService()
调用者与服务绑定在一起,调用者一旦退出,服务也会一起终止。
生命周期:onCreate():创建服务--》onBind():绑定服务,服务开始运行--》onUnbind():取消绑定--》onDestroy() :服务被停止
【详细说明:】
在程序中调用:context.bindService()会触发执行Service生命周期中的onCreate()、onBind()回调方法,此时服务开始运行;
onBind将返回给客户端一个IBind接口实例,IBind允许客户端回调服务的方法,比如得到Service运行的状态或其他操作。此后调用者(Context,例如Activity)会和Service绑定在一起;
如果调用Service的调用者Context退出了,那么会依次调用Service生命周期中的onUnbind()、onDestroy()回调方法,会让服务停止;
所以BindService的生命周期为:onCreate --> onBind(只一次,不可多次绑定) --> onUnbind --> onDestory。
生命周期参照下图:
3)根据启动方式不同又可以将本地服务分为:启动服务Started Service和绑定服务Bound Service
①Started Service启动方式
// 第一种启动方式
serviceIntent = new Intent(this, MyFirstService.class);
startService(serviceIntent);
Service类
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.util.Log;
public class MyFirstService extends Service {
String TAG="MyFirstService";
@Override
public void onCreate() {
super.onCreate();
//只会执行一次
Log.i(TAG,"服务方法 onCreate运行");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(TAG,"服务方法 onStartCommand运行");
//当Service运行的进程被Android系统强制杀掉之后,不会重新创建(发生车祸,被撞死了)
return START_NOT_STICKY;
// // 表示被强制杀死后会重启,并且保留Intent里面的信息(车祸后醒来没有记忆)
// return START_STICKY;
// // 表示被强制杀死后会重启,并且保留Intent里面的信息(车祸后醒来还有记忆)
// return START_REDELIVER_INTENT;
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
第一次启动效果
②绑定服务Bound Service
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import com.rongyao.servicedemo.service.MySecondService;
public class Main2Activity extends AppCompatActivity {
private MySecondService.MyBinder binder;
private String TAG = "Main2Activity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
//绑定服务
Intent intent = new Intent(Main2Activity.this, MySecondService.class);
bindService(intent, conn, Context.BIND_AUTO_CREATE);
}
@Override
protected void onDestroy() {
//取消服务绑定
unbindService(conn);
super.onDestroy();
}
ServiceConnection conn = new ServiceConnection() {
@Override
public void onServiceDisconnected(ComponentName name) {
}
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
binder = (MySecondService.MyBinder) service;
//获取Service,通过接口回调返回数据
binder.getService().setCallBack(new CallBack() {
@Override
public void back(String data) {
Log.i(TAG,"由服务传回的数据=="+data);
}
});
//调用方法,把字符串传入Service
binder.setData("传入服务数据");
}
};
}
服务类
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.util.Log;
import com.rongyao.servicedemo.CallBack;
public class MySecondService extends Service {
String TAG = "MySecondService";
String data;
CallBack callBack;
private boolean connecting = false;
@Override
public void onCreate() {
super.onCreate();
//只会执行一次
connecting = true;
new Thread(new Runnable() {
@Override
public void run() {
int i = 0;
while (connecting == true) {
i++;
if (callBack != null) {
callBack.back("hahah" + i);
}
if(i>5)
connecting=false;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(TAG, "服务方法 onStartCommand运行");
//当Service运行的进程被Android系统强制杀掉之后,不会重新创建(发生车祸,被撞死了)
return START_NOT_STICKY;
}
public void setCallBack(CallBack callBack) {
this.callBack = callBack;
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return new MyBinder();
}
public class MyBinder extends Binder {
public void setData(String data) {
MySecondService.this.data = data;
//由Activity传入数据
Log.i(TAG, data);
}
public MySecondService getService() {
return MySecondService.this;
}
}
}
运行效果
2、远程服务Remote Service:
用于android系统内部的应用程序之间。可以定义接口并把接口暴露出来,以便其他应用进行操作。可被其他应用程序复用,比如天气预报服务,其他应用程序不需要再写这样的服务,调用已有的即可。
CSDN下载地址:https://download.csdn.net/download/u010350891/11150318