当前位置: 首页 > 科技观察

从Service到WorkManager

时间:2023-03-19 19:58:03 科技观察

前言关于Service,想必大家再熟悉不过了。今天我们就来回顾一下它的用途、概念、区别、变更历史等。概念和用途Service是一个应用组件,可以在不提供接口的情况下在后台执行长时间运行的操作两种启动方式:startService()生命周期为:onCreate()->onStartCommand()->onDestory()bindService()生命周期为:onCreate()->onBind()->onUnBind()->onDestory()其中,需要注意的是返回onStartCommand方法的值有3个常量:1)START_NOT_STICKY,服务终止后,除非有东西要传递SuspendIntent,否则系统不会重建服务。2)START_STICKY,服务终止后,会自动重启服务并调用onStartCommand(),但不会重新传递上一个Intent。3)START_REDELIVER_INTENT,服务终止后,将重新构建服务,并调用onStartCommand(),调用上次传递给服务的Intent。当然,如果最后要使用,还需要在manifest文件中注册:。..Service和childThread关于Service,我的第一反应是后台运行的服务。关于背景,我的第一反应又是子线程。那么Service和子线程是什么关系呢?服务有两个重要元素:长期运行。Activity被销毁,程序关闭后Service可以继续运行。不提供接口的应用程序组件。这其实就说明了背景的意思。Service的后台是指不与界面交互,不依赖UI元素。而且比较关键的一点是Service也在主线程中运行。所以后台运行的Service和后台运行的线程是有很大区别的。首先,运行的线程不同。Service仍然运行在主线程上,子线程必须开辟一个新的线程。二是背景概念不同。Service后台是指不与界面交互,子线程后台是指异步操作。最后,Service作为四大组件之一,控制起来比较方便,只要有上下文就可以控制。当然,虽然两者的理念不同,但合作的领域还是很多的。Service作为后台运行的组件,很多时候其实是用来做耗??时操作的,所以运行在主线程上的Service肯定不能直接进行耗时操作,这就需要子线程了。开启一个后台Service,然后在Service中进行子线程操作。这种组合为项目带来了更大的可能性。Google也考虑到了这一点,设计了IntentService这个组合良好的组件供我们使用。IntentServiceIntentService是一个继承自Service的类,有自己的工作线程和Handler,线程任务结束后自动销毁。源码很简单:@OverridepublicvoidonCreate(){super.onCreate();//新建线程并startHandlerThreadthread=newHandlerThread("IntentService["+mName+"]");thread.start();mServiceLooper=thread。getLooper();//创建新线程对应的handlermServiceHandler=newServiceHandler(mServiceLooper);}@OverridepublicvoidonStart(@NullableIntentintent,intstartId){//服务启动后发送消息给handlerMessagemsg=mServiceHandler.obtainMessage();msg.arg1=startId;msg.obj=intent;mServiceHandler.sendMessage(msg);}privatefinalclassServiceHandlerextendsHandler{publicServiceHandler(Looperlooper){super(looper);}@OverridepublicvoidhandleMessage(Messagemsg){//handler收到消息后调用onHandleIntent方法onHandleIntent((Intent)msg.obj);stopSelf(msg.arg1);}}前面说过,Service的特性确实给了我们更多的可能性。我们可以在后台静默下载项目需要的东西,发送心跳包,处理一些数据。但也正是因为背景的隐蔽性,也带来了隐私方面的隐患和弊端。App可以在后台操作用户数据,下载应用无关文件等。因此,为了保护用户隐私,谷歌从Android8.0开始对后台服务进行了限制。后台Service和前台Service这里涉及到Service的分类。如果按是否不敏感来分类,Service可以分为前台和后台。前台Service会通过通知让用户感知后台有这么一个东西在运行。比如音乐类APP,在后台播放音乐的时候,可以发现前台一直显示一个通知,让用户知道后台有这样一个音乐相关的服务。在Android8.0中,谷歌要求如果程序在后台,则不能创建后台服务,已经启动的后台服务会在一定时间后停止。所以推荐使用前台Service,优先级高,不易被破坏。使用方法如下:startForegroundService(intent);publicvoidonCreate(){super.onCreate();Notificationnotification=newNotification.Builder(this).setChannelId(CHANNEL_ID).setContentTitle("mainservice")//Title.setContentText("Running...")//Content.setSmallIcon(R.mipmap.ic_launcher).build();startForeground(1,notification);后台任务呢?官方推荐使用JobScheduler。JobScheduler任务调度JobScheduler,Android5.0推出。(有的朋友可能会觉得陌生,其实他也是通过Service实现的,后面会讲到)它能做的就是在你指定的需求下自动执行任务。比如在指定时间、网络为WIFI时、设备空闲时、充电时等各种情况下自动后台运行。于是Google让它替换了后台Service的一些功能,使用:首先,创建一个JobService:publicclassMyJobServiceextendsJobService{@OverridepublicbooleanonStartJob(JobParametersparams){returnfalse;}@OverridepublicbooleanonStopJob(JobParametersparams){returnfalse;}}然后,注册这个服务(因为JobService也是Service)最后创建一个JobInfo,执行JobSchedulerscheduler=(JobScheduler)getSystemService(Context.JOB_SCHEDULER_SERVICE);ComponentNamejobService=newComponentName(this,MyJobService.class);JobInfojobInfo=newJobInfo.Builder(ID,jobService).setMinimuLatency(5000)//任务的最小延迟时间。setOverrideDeadline(60000)//任务截止时间,当截止时间不满足指定条件,也会开始执行。setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED)//网络条件,默认值NETWORK_TYPE_NONE.setRequiresCharging(true)//是否充电.setRequiresDeviceIdle(false)//设备是否空闲.setPersisted(true)//设备重启后是否继续执行.setBackoffCriteria(3000,JobInfo.BACKOFF_POLICY_LINEAR)//设置退避/重试strategy.build();scheduler.schedule(jobInfo);简单说明一下原理:JobSchedulerService是在SystemServer中启动的一个服务,然后遍历未完成的任务,通过Binder找到对应的JobService,执行onStartJob方法,完成任务。详见参考链接的分析。所以我知道5.0之后,如果需要执行后台任务,尤其是需要满足一定条件的任务,比如网络供电等,可以使用JobScheduler。可能有人会问,5.0之前怎么办?在某些情况下,您可以使用GcmNetworkManager或BroadcastReceiver来处理任务需求。Google也考虑到了这一点,所以将5.0之后的JobScheduler与5.0之前的GcmNetworkManager、GcmNetworkManager、AlarmManager以及任务相关的API结合起来设计了WorkManager。WorkManagerWorkManager是一种API,可让您轻松安排即使在退出应用程序或重新启动设备后也应运行的可延迟异步任务。作为Jetpack的一员,它并不是很新鲜。它的本质是将现有的与任务调度相关的API组合起来,然后根据版本要求执行这些任务。官网上有一张图:那么WorkManager可以做什么呢??1、对于一些任务约束可以很好地执行,比如需要在网络、设备空闲状态、存储空间充足等条件下执行的任务。2、可重复、一次性、稳定地执行任务。包括在设备重启后继续任务的能力。3.您可以定义不同工作任务的内聚关系。例如,设置一个接一个任务。简而言之,它是在后台执行任务的绝佳工具。参考https://developer.android.google.cn/guide/components/services#Lifecyclehttp://githyuan.com/2017/03/10/job_scheduler_service/上块。转载本文请联系代码上的积木公众号。