8.1服务的创建
服务(Service)是Android中的四大组件之一,它能够长期在后台运行且不提供用户界面。即使用户切到另一应用程序,服务仍可以在后台运行。
8.1.1理论概述
Service是什么?
- Service是一个应用组件,它用来在后台完成一个时间跨度比较大的工作且没有关联任何界面
- 一个Service可以完成下面这些工作:访问网络、播放音乐、文件IO操作、大数据量的数据库操作
- 服务的特点:1.Service在后台运行,不用与用户进行交互;2.即使程序被切换到后台,或者用户打开新的应用,服务仍可运行;3.服务并非运行在独立的进程中,而是依赖于创建服务的应用程序进程。如果某个应用进程被杀掉,该服务也会停止;4.在默认情况下,Service运行在应用程序进程的主线程(UI线程)中,如果需要在Service中处理一些网络连接等耗时的操作,那么应该将这些任务放在Service的分线程中处理,避免阻塞用户界面
区别Service与Activity
- Activity:Activity对应一个界面;应用退出,Activity对象就会死亡;应用再次进入,启动的Activity对象是重新创建的
- Service:不与任何界面关联,绝不会到前台来;应用退出,Service仍在运行;应用再次进入,启动的Service还是前面运行的Service对象
- Activity与Service的选择标准:如果某个应用程序组件需要运行时向用户呈现某种界面,或者该程序需要与用户交互,就需要使用Activity,否则就应该考虑使用Service。
8.1.2服务的创建方式与创建Activity类似,只需要继承Service类,然后在清单文件中注册即可
-
创建服务
普通模式:自定义类继承Service;AndroidManifest.xml中注册服务intent=newIntent(MainActivity.this,MyService.class); startService(intent); Log.i("service=","服务启动成功");
绑定模式:构建IBinder对象;自定义IBinder类继承Binder类;添加自定义方法。
class MyIBinder extends Binder{ //方法:与服务端的数据局传送。 public MyService test(){ System.out.println("音乐开始播放"); return MyService.this; } }
onBind方法返回自定义IBinder对象。
服务端:绑定服务// 1.构建Intent对象 intent=new Intent(MainActivity.this,MyService.class); //调用绑定方法 onCreate→onBinder→回调是ServiceConnection接口里的onServiceConnected //MyService s=new MyService(); bindService(intent,conn,Service.BIND_AUTO_CREATE);
创建自定义类,实现ServiceConnection接口,重写接口方法。
class MyServiceConnection implements ServiceConnection{ //服务端与服务连接成功系统会调用该方法:IBinder service传递过来 @Override public void onServiceConnected(ComponentName name,IBinder service){ System.out.println("onServiceConnected…"); MyService.MyIBinder binder=(MyService.MyIBinder)service; binder.test(); } //意外中断连接调用该方法;解绑不会调用该方法。 @Override public void onServiceDisconnected(ComponentName name){ System.out.println("onServiceDisconnected…") } }
8.2服务的生命周期
与其他组件不同的是,Service不能自己主动运行,需要调用相应的方法来启动
启动服务的方法是Context.startService()和Context.bindService()。使用不同的方法启动服务,服务的生命周期也会不同。
-
startService方式开启服务的生命周期
服务会执行onCreate()→onStartCommand()方法,服务处于运行状态,直到自身调用stopSelf()方法或者其他组件调用stopService()方法时服务停止,最终被系统销毁。
服务会长期的在后台运行,并且服务的状态与开启者的状态没有关系 -
bindService方式开启服务的生命周期
服务会执行onCreat()→onBind()方法,服务处于绑定状态,客户端通过unbindService()方法关闭连接,解除绑定时,系统将直接销毁服务。
服务与开启者的状态有关,当调用者销毁了,服务也会被销毁。
8.3.2bind方式启动服务
当程序使用startService()和stopService()启动、关闭服务时,服务与调用者之间基本不存在太多的关联,也无法与访问者进行通信、数据交互等。如果服务需要与调用者进行方法调用和数据交互时,应该使用bindService()和unbindService()启动、关闭服务。
bindService(Intent service,ServiceConnection conn,int flags)
Intent对象用于指定要启动的Service
ServiceConnection对象用于监听调用者与Service的连接状态
flags指定绑定时是否自动创建Service(如果Service还未创建)
8.4服务通信
8.4.1本地服务通信和远程服务通信
远程服务通信是通过AIDL实现的,它是一种接口定义语言,其语法格式非常简单,与Java中定义接口很相似。定义好AIDL接口之后,接着需要在应用程序中创建Service的子类。该Service的onBind()方法所返回的IBinder对象应该是ADT所生成的IService.Stub的子类。
运行流程:
3.远程服务
注册文件配置:android:process=":remote"
和主线程分离
4.服务销毁
如果启动服务:startService(),bindService(intent,conn,Service.BIND_AUTO_CREATE);同时都使用了,只单击某一个stopService,unbindService停止都不会调用onDestroy();必须这个停止方法都点击一次
5.前台服务8.0以上系统
-
配置权限
<!--配置前提服务权限--> <uses-permission android:name="android.permission.FOREGROUND_SERVICE"></uses-permission>
-
创建消息通知
//1.构建消息管理器 NotificationManager manager=(NotificationManager)getSystemService(NOTIFICATION_SERVICE); //2.构建消息通道 NotificationChannel channe1=new NotificationChanne1(ID,NAME,NotificationManager.IMPORTANCE_HIGH); //3.创建消息通道 manager.createNotificationChanne1(channe1); //4.构建消息 Notification notification=new Notification.Builder(this,ID) .setContentTitle("收到一条重要通知") .setContentText("这是重要通知") .setSmallIcon(R.mipmap.ic_launcher) .build(); //5.发送前台服务消息 startForeground(1,notification);