从Service到WorkManager

前言

关于Service,想必大家都太熟悉了,今天我们就再回顾下它的使用、概念、区别、变更历史等等。

概念和使用

Service 是一种可在后台执行长时间运行操作而不提供界面的应用组件

两种启动方式:

startService() 生命周期为:onCreate() -> onStartCommand() -> onDestory() bindService() 生命周期为:onCreate() -> onBind() -> onUnBind() -> onDestory()

其中要注意的是onStartCommand方法的返回值,有三种常量:

1) START_NOT_STICKY,终止服务后,除非除非有待传递的挂起 Intent,否则系统不会重建服务。

2) START_STICKY,终止服务后,会自动重新服务并调用 onStartCommand(),但不会重新传递最后一个 Intent。

3) START_REDELIVER_INTENT,终止服务后,会重建服务,并通过传递给服务的最后一个 Intent 调用 onStartCommand()。

当然,最后要使用的话还要在清单文件中注册:

<service android:enabled=["true" | "false"]     android:exported=["true" | "false"]     android:icon="drawable resource"     android:isolatedProcess=["true" | "false"]     android:label="string resource"     android:name="string"     android:permission="string"     android:process="string" >     . . . </service> 

Service与子线程

关于Service,我的第一反应是运行在后台的服务。云服务器提供商

关于后台,我的第一反应又是子线程。

那么Service和子线程到底是什么关系呢?

Service有两个比较重要的元素:

长时间运行。Service可以在Activity被销毁,程序被关闭之后都可以继续运行。 不提供界面的应用组件。这其实解释了后台的意义,Service的后台指的是不和界面交互,不依赖UI元素。

而且比较关键的点是,Service也是运行在主线程之中。

所以运行在后台的Service和运行在后台的线程区别还是挺大的。

首先,所运行的线程不同。Service还是运行在主线程,亿华云计算而子线程肯定是开辟了新的线程。 其次,后台的概念不同。Service的后台指的是不与界面交互,子线程的后台指的是异步运行。 最后,Service作为四大组件之一,控制它也更方便,只要有上下文就可以对其进行控制。

当然,虽然两者概念不同,但是还是有很多合作之处。

Service作为后台运行的组件,其实很多时候也会被用来做耗时操作,那运行在主线程的Service肯定不能直接进行耗时操作,这就需要子线程了。

开启一个后台Service,然后在Service里面进行子线程操作,这样的结合给项目带来的b2b供应网可能性就更大了。

Google也是考虑到这一点,设计出了IntentService这种已经结合好的组件供我们使用。

IntentService

IntentService 是一个继承自Service,自带工作线程和Handler,并且线程任务结束后自动销毁的一个类。

源码很简单:

@Override public void onCreate() {            super.onCreate();           //创建新线程并start     HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");     thread.start();     mServiceLooper = thread.getLooper();     //创建新线程对应的handler     mServiceHandler = new ServiceHandler(mServiceLooper); } @Override public void onStart(@Nullable Intent intent, int startId) {      //service启动后发送消息给handler     Message msg = mServiceHandler.obtainMessage();     msg.arg1 = startId;     msg.obj = intent;     mServiceHandler.sendMessage(msg); } private final class ServiceHandler extends Handler {      public ServiceHandler(Looper looper) {          super(looper);     }     @Override     public void handleMessage(Message msg) {              //handler收到消息后调用onHandleIntent方法         onHandleIntent((Intent)msg.obj);         stopSelf(msg.arg1);     } } 

弊端

之前也说了,Service这些特性确实给了我们更多的可能性,我们可以在后台静默下载项目需要的东西、可以发心跳包、可以处理一些数据。

但是,也正是因为后台无感知的特性,也带来了隐私方面的隐患和弊端。

App可以在后台操作用户数据,下载应用无关的文件等等。

所以Google为了保护用户隐私,在Android8.0开始,限制了后台Service。

后台和前台Service

这就涉及到Service的分类了。

如果从是否无感知来分类,Service可以分为前台和后台。前台Service会通过通知的方式让用户感知到,后台有这么一个玩意在运行。

比如音乐类APP,在后台播放音乐的同时,可以发现始终有一个通知显示在前台,让用户知道,后台有一个这么音乐相关的服务。

在Android8.0,Google要求如果程序在后台,那么就不能创建后台服务,已经开启的后台服务会在一定时间后被停止。

所以,建议使用前台Service,它拥有更高的优先级,不易被销毁。使用方法如下:

startForegroundService(intent);  public void onCreate() {       super.onCreate();      Notification notification = new Notification.Builder(this)              .setChannelId(CHANNEL_ID)              .setContentTitle("主服务")//标题              .setContentText("运行中...")//内容              .setSmallIcon(R.mipmap.ic_launcher)              .build();      startForeground(1,notification);  }    <!--android 9.0上使用前台服务,需要添加权限-->  <uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> 
滇ICP备2023000592号-31