简介
提供后台长期运行的服务(复杂计算、音乐播放、下载等)
类型
按运行地点分类
本地服务LocalService:
运行在主线程,主线程结束,服务也结束
因为运行在主线程,通信方便
远程服务RemoteService:
运行在独立进程,服务常驻后台,不受Activity影响
按运行类型分类
前台服务:
在通知栏显示通知(用户可看到)
服务时,需要用户知道并进行相关操作(服务终止时,通知栏通知也会消失)
后台服务:
后台(用户无法看到)
类似天气、时间更新等,无需用户知道或操作的任务
按功能分类
不可通信的后台服务:
用startService()启动,调用者退出后service仍然存在
服务不需与Activity或Service通信
可通信的后台服务:
①用bindService()启动,调用者退出后,随之销毁
②用startService()、bindService()启动,随之销毁
使用
本地Service
创建子类继承Service类
public class MyService extends Service {
//启动Service之后,就可以在onCreate()或onStartCommand()方法里去执行一些具体的逻辑
@Override
public void onCreate() {
super.onCreate();
System.out.println("执行了onCreat()");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
System.out.println("执行了onStartCommand()");
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
super.onDestroy();
System.out.println("执行了onDestory()");
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
需要重写上述方法
构建用于启动Service的Intent对象
//构建启动服务的Intent对象
Intent startIntent = new Intent(this, MyService.class);
//构建停止服务的Intent对象
Intent stopIntent = new Intent(this, MyService.class);
调用startService()启动Service,调用stopService()停止服务
//调用startService()方法-传入Intent对象,以此启动服务
startService(startIntent);
//调用stopService()方法-传入Intent对象,以此停止服务
stopService(stopIntent);
在AndroidManifest中注册Service
//注册Service服务
<service android:name=".MyService">
</service>
注:通常在service的onCreate和onStartCommand中执行具体逻辑
可通信Service
构造Service类
public class MyService extends Service {
private MyBinder mBinder = new MyBinder();
@Override
public void onCreate() {
super.onCreate();
System.out.println("执行了onCreat()");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
System.out.println("执行了onStartCommand()");
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
super.onDestroy();
System.out.println("执行了onDestory()");
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
System.out.println("执行了onBind()");
//返回实例
return mBinder;
}
@Override
public boolean onUnbind(Intent intent) {
System.out.println("执行了onUnbind()");
return super.onUnbind(intent);
}
//新建一个子类继承自Binder类
class MyBinder extends Binder {
public void service_connect_Activity() {
System.out.println("Service关联了Activity,并在Activity执行了Service的方法");
}
}
}
相比于本地Service多了Binder对象及其bind、unbind方法
服务实际使用
private MyService.MyBinder myBinder;
//创建ServiceConnection的匿名类
private ServiceConnection connection = new ServiceConnection() {
//重写onServiceConnected()方法和onServiceDisconnected()方法
//在Activity与Service建立关联和解除关联的时候调用
@Override
public void onServiceDisconnected(ComponentName name) {
}
//在Activity与Service关联的时候调用
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
//实例化Service的内部类myBinder
//通过向下转型得到了MyBinder的实例
myBinder = (MyService.MyBinder) service;
//在Activity调用Service类的方法
myBinder.service_connect_Activity();
}
};
获取binder实例,并且设置关联建立、销毁时处理
Intent startIntent = new Intent(this, MyService.class);
//调用startService()方法-传入Intent对象,以此启动服务
startService(startIntent);
Intent stopIntent = new Intent(this, MyService.class);
//调用stopService()方法-传入Intent对象,以此停止服务
stopService(stopIntent);
Intent bindIntent = new Intent(this, MyService.class);
bindService(bindIntent,connection,BIND_AUTO_CREATE);
//参数说明
//第一个参数:Intent对象
//第二个参数:上面创建的Serviceconnection实例
//第三个参数:标志位
//这里传入BIND_AUTO_CREATE表示在Activity和Service建立关联后自动创建Service
//这会使得MyService中的onCreate()方法得到执行,但onStartCommand()方法不会执行
//调用unbindService()解绑服务
//参数是上面创建的Serviceconnection实例
unbindService(connection);
前台Service
前台Service优先级高于后台Service
具体使用:
@Override
public void onCreate() {
super.onCreate();
System.out.println("执行了onCreat()");
//添加下列代码将后台Service变成前台Service
//构建"点击通知后打开MainActivity"的Intent对象
Intent notificationIntent = new Intent(this,MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this,0,notificationIntent,0);
//新建Builer对象
Notification.Builder builer = new Notification.Builder(this);
builer.setContentTitle("前台服务通知的标题");//设置通知的标题
builer.setContentText("前台服务通知的内容");//设置通知的内容
builer.setSmallIcon(R.mipmap.ic_launcher);//设置通知的图标
builer.setContentIntent(pendingIntent);//设置点击通知后的操作
Notification notification = builer.getNotification();//将Builder对象转变成普通的notification
startForeground(1, notification);//让Service变成前台Service,并在系统的状态栏显示出来
}
相比原有Service类,在onCreate中修改即可(该效果为点击前台按钮后,启动MainActivity)
使用场景
本地服务
执行需要依赖于某个进程的服务(如音乐播放)
远程服务
系统级别服务
前台服务
需要让用户知道并执行相关操作(音乐播放器等)
后台服务
无需用户知晓相关信息
不可通信的后台服务
长期在后台运行,无需与Activity、Service通信(startService()启动)
可通信的后台服务
后台服务需要通信(如控制服务开始等)(使用bindService()启动,第一次调用才会创建实例运行服务,节约系统资源)
注
Service:运行于主线程,故不可做耗时操作(可以在Service中创建工作线程进行操作),不依赖UI/Activity,只要进程在,Service就一直运行
Thread:运行于工作线程,需要依赖于Activity(与Activity共亡)
由上述可知,两者通常结合使用,在Service中将耗时操作托付给Thread创建子线程执行
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
//新建工作线程
new Thread(new Runnable() {
@Override
public void run() {
// 开始执行后台任务
}
}).start();
return super.onStartCommand(intent, flags, startId);
}
class MyBinder extends Binder {
public void service_connect_Activity() {
//新建工作线程
new Thread(new Runnable() {
@Override
public void run() {
// 执行具体的下载任务
}
}).start();
}
}