日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
從Service到WorkManager

前言

創(chuàng)新互聯(lián)建站專注于合作網(wǎng)站建設(shè)服務(wù)及定制,我們擁有豐富的企業(yè)做網(wǎng)站經(jīng)驗(yàn)。 熱誠(chéng)為您提供合作營(yíng)銷型網(wǎng)站建設(shè),合作網(wǎng)站制作、合作網(wǎng)頁(yè)設(shè)計(jì)、合作網(wǎng)站官網(wǎng)定制、成都小程序開(kāi)發(fā)服務(wù),打造合作網(wǎng)絡(luò)公司原創(chuàng)品牌,更為您提供合作網(wǎng)站排名全網(wǎng)營(yíng)銷落地服務(wù)。

關(guān)于Service,想必大家都太熟悉了,今天我們就再回顧下它的使用、概念、區(qū)別、變更歷史等等。

概念和使用

Service 是一種可在后臺(tái)執(zhí)行長(zhǎng)時(shí)間運(yùn)行操作而不提供界面的應(yīng)用組件

兩種啟動(dòng)方式:

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

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

1) START_NOT_STICKY,終止服務(wù)后,除非除非有待傳遞的掛起 Intent,否則系統(tǒng)不會(huì)重建服務(wù)。

2) START_STICKY,終止服務(wù)后,會(huì)自動(dòng)重新服務(wù)并調(diào)用 onStartCommand(),但不會(huì)重新傳遞最后一個(gè) Intent。

3) START_REDELIVER_INTENT,終止服務(wù)后,會(huì)重建服務(wù),并通過(guò)傳遞給服務(wù)的最后一個(gè) Intent 調(diào)用 onStartCommand()。

當(dāng)然,最后要使用的話還要在清單文件中注冊(cè):

 
 
 
 
  1.     android:exported=["true" | "false"] 
  2.     android:icon="drawable resource" 
  3.     android:isolatedProcess=["true" | "false"] 
  4.     android:label="string resource" 
  5.     android:name="string" 
  6.     android:permission="string" 
  7.     android:process="string" > 
  8.     . . . 
  9.  

Service與子線程

關(guān)于Service,我的第一反應(yīng)是運(yùn)行在后臺(tái)的服務(wù)。

關(guān)于后臺(tái),我的第一反應(yīng)又是子線程。

那么Service和子線程到底是什么關(guān)系呢?

Service有兩個(gè)比較重要的元素:

  • 長(zhǎng)時(shí)間運(yùn)行。Service可以在Activity被銷毀,程序被關(guān)閉之后都可以繼續(xù)運(yùn)行。
  • 不提供界面的應(yīng)用組件。這其實(shí)解釋了后臺(tái)的意義,Service的后臺(tái)指的是不和界面交互,不依賴UI元素。

而且比較關(guān)鍵的點(diǎn)是,Service也是運(yùn)行在主線程之中。

所以運(yùn)行在后臺(tái)的Service和運(yùn)行在后臺(tái)的線程區(qū)別還是挺大的。

  • 首先,所運(yùn)行的線程不同。Service還是運(yùn)行在主線程,而子線程肯定是開(kāi)辟了新的線程。
  • 其次,后臺(tái)的概念不同。Service的后臺(tái)指的是不與界面交互,子線程的后臺(tái)指的是異步運(yùn)行。
  • 最后,Service作為四大組件之一,控制它也更方便,只要有上下文就可以對(duì)其進(jìn)行控制。

當(dāng)然,雖然兩者概念不同,但是還是有很多合作之處。

Service作為后臺(tái)運(yùn)行的組件,其實(shí)很多時(shí)候也會(huì)被用來(lái)做耗時(shí)操作,那運(yùn)行在主線程的Service肯定不能直接進(jìn)行耗時(shí)操作,這就需要子線程了。

開(kāi)啟一個(gè)后臺(tái)Service,然后在Service里面進(jìn)行子線程操作,這樣的結(jié)合給項(xiàng)目帶來(lái)的可能性就更大了。

Google也是考慮到這一點(diǎn),設(shè)計(jì)出了IntentService這種已經(jīng)結(jié)合好的組件供我們使用。

IntentService

IntentService 是一個(gè)繼承自Service,自帶工作線程和Handler,并且線程任務(wù)結(jié)束后自動(dòng)銷毀的一個(gè)類。

源碼很簡(jiǎn)單:

 
 
 
 
  1. @Override 
  2. public void onCreate() { 
  3.           super.onCreate(); 
  4.           //創(chuàng)建新線程并start 
  5.     HandlerThread thread = new HandlerThread("IntentService[" + mName + "]"); 
  6.     thread.start(); 
  7.     mServiceLooper = thread.getLooper(); 
  8.     //創(chuàng)建新線程對(duì)應(yīng)的handler 
  9.     mServiceHandler = new ServiceHandler(mServiceLooper); 
  10.  
  11. @Override 
  12. public void onStart(@Nullable Intent intent, int startId) { 
  13.     //service啟動(dòng)后發(fā)送消息給handler 
  14.     Message msg = mServiceHandler.obtainMessage(); 
  15.     msg.arg1 = startId; 
  16.     msg.obj = intent; 
  17.     mServiceHandler.sendMessage(msg); 
  18.  
  19. private final class ServiceHandler extends Handler { 
  20.     public ServiceHandler(Looper looper) { 
  21.         super(looper); 
  22.     } 
  23.     @Override 
  24.     public void handleMessage(Message msg) { 
  25.             //handler收到消息后調(diào)用onHandleIntent方法 
  26.         onHandleIntent((Intent)msg.obj); 
  27.         stopSelf(msg.arg1); 
  28.     } 

弊端

之前也說(shuō)了,Service這些特性確實(shí)給了我們更多的可能性,我們可以在后臺(tái)靜默下載項(xiàng)目需要的東西、可以發(fā)心跳包、可以處理一些數(shù)據(jù)。

但是,也正是因?yàn)楹笈_(tái)無(wú)感知的特性,也帶來(lái)了隱私方面的隱患和弊端。

App可以在后臺(tái)操作用戶數(shù)據(jù),下載應(yīng)用無(wú)關(guān)的文件等等。

所以Google為了保護(hù)用戶隱私,在Android8.0開(kāi)始,限制了后臺(tái)Service。

后臺(tái)和前臺(tái)Service

這就涉及到Service的分類了。

如果從是否無(wú)感知來(lái)分類,Service可以分為前臺(tái)和后臺(tái)。前臺(tái)Service會(huì)通過(guò)通知的方式讓用戶感知到,后臺(tái)有這么一個(gè)玩意在運(yùn)行。

比如音樂(lè)類APP,在后臺(tái)播放音樂(lè)的同時(shí),可以發(fā)現(xiàn)始終有一個(gè)通知顯示在前臺(tái),讓用戶知道,后臺(tái)有一個(gè)這么音樂(lè)相關(guān)的服務(wù)。

在Android8.0,Google要求如果程序在后臺(tái),那么就不能創(chuàng)建后臺(tái)服務(wù),已經(jīng)開(kāi)啟的后臺(tái)服務(wù)會(huì)在一定時(shí)間后被停止。

所以,建議使用前臺(tái)Service,它擁有更高的優(yōu)先級(jí),不易被銷毀。使用方法如下:

 
 
 
 
  1. startForegroundService(intent); 
  2.  
  3.  public void onCreate() { 
  4.      super.onCreate(); 
  5.      Notification notification = new Notification.Builder(this) 
  6.              .setChannelId(CHANNEL_ID) 
  7.              .setContentTitle("主服務(wù)")//標(biāo)題 
  8.              .setContentText("運(yùn)行中...")//內(nèi)容 
  9.              .setSmallIcon(R.mipmap.ic_launcher) 
  10.              .build(); 
  11.      startForeground(1,notification); 
  12.  }   
  13.  
  14.  
  15.   
  16.   

那后臺(tái)任務(wù)該怎么辦呢?官方建議使用 JobScheduler 。

JobScheduler

任務(wù)調(diào)度JobScheduler,Android5.0被推出。(可能有的朋友感覺(jué)比較陌生,其實(shí)他也是通過(guò)Service實(shí)現(xiàn)的,這個(gè)待會(huì)再說(shuō))

它能做的工作就是可以在你所規(guī)定的要求下進(jìn)行自動(dòng)任務(wù)執(zhí)行。比如規(guī)定時(shí)間、網(wǎng)絡(luò)為WIFI情況、設(shè)備空閑、充電時(shí)等各種情況下后臺(tái)自動(dòng)運(yùn)行。

所以Google讓它來(lái)替代后臺(tái)Service的一部分功能,使用:

首先,創(chuàng)建一個(gè)JobService:

 
 
 
 
  1. public class MyJobService extends JobService { 
  2.  
  3.     @Override 
  4.     public boolean onStartJob(JobParameters params) { 
  5.         return false; 
  6.     } 
  7.  
  8.     @Override 
  9.     public boolean onStopJob(JobParameters params) { 
  10.         return false; 
  11.     } 
  12. }   

然后,注冊(cè)這個(gè)服務(wù)(因?yàn)镴obService也是Service)

 
 
 
 
  1.     android:permission="android.permission.BIND_JOB_SERVICE" /> 

最后,創(chuàng)建一個(gè)JobInfo并執(zhí)行

 
 
 
 
  1. JobScheduler scheduler = (JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE);   
  2.  ComponentName jobService = new ComponentName(this, MyJobService.class); 
  3.  
  4.  JobInfo jobInfo = new JobInfo.Builder(ID, jobService)  
  5.          .setMinimumLatency(5000)// 任務(wù)最少延遲時(shí)間  
  6.          .setOverrideDeadline(60000)// 任務(wù)deadline,當(dāng)?shù)狡跊](méi)達(dá)到指定條件也會(huì)開(kāi)始執(zhí)行  
  7.          .setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED)// 網(wǎng)絡(luò)條件,默認(rèn)值NETWORK_TYPE_NONE 
  8.          .setRequiresCharging(true)// 是否充電  
  9.          .setRequiresDeviceIdle(false)// 設(shè)備是否空閑 
  10.          .setPersisted(true) //設(shè)備重啟后是否繼續(xù)執(zhí)行 
  11.          .setBackoffCriteria(3000,JobInfo.BACKOFF_POLICY_LINEAR) //設(shè)置退避/重試策略 
  12.          .build();   
  13.  scheduler.schedule(jobInfo); 

簡(jiǎn)單說(shuō)下原理:

JobSchedulerService是在SystemServer中啟動(dòng)的服務(wù),然后會(huì)遍歷沒(méi)有完成的任務(wù),通過(guò)Binder找到對(duì)應(yīng)的JobService,執(zhí)行onStartJob方法,完成任務(wù)。具體可以看看參考鏈接的分析。

所以也就知道了,在5.0之后,如果有需要后臺(tái)任務(wù)執(zhí)行,特別是需要滿足一定條件觸發(fā)的任務(wù),比如網(wǎng)絡(luò)電量等等情況,就可以使用JobScheduler。

有的人可能要問(wèn)了,5.0之前怎么辦呢?

可以使用GcmNetworkManager或者BroadcastReceiver等處理部分情況下的任務(wù)需求。

Google也是考慮到了這一點(diǎn),所以將5.0之后的JobScheduler和5.0之前的GcmNetworkManager、GcmNetworkManager、AlarmManager等和任務(wù)相關(guān)的API相結(jié)合,設(shè)計(jì)出了WorkManager。

WorkManager

WorkManager 是一個(gè) API,可供您輕松調(diào)度那些即使在退出應(yīng)用或重啟設(shè)備后仍應(yīng)運(yùn)行的可延期異步任務(wù)。

作為Jetpack的一員,并不算很新的內(nèi)容,它的本質(zhì)就是結(jié)合已有的任務(wù)調(diào)度相關(guān)的API,然后根據(jù)版本需求等來(lái)執(zhí)行這些任務(wù),官網(wǎng)有一張圖:

所以WorkManager到底能做什么呢?

  • 1、對(duì)于一些任務(wù)約束能很好的執(zhí)行,比如網(wǎng)絡(luò)、設(shè)備空閑狀態(tài)、足夠存儲(chǔ)空間等條件下需要執(zhí)行的任務(wù)。
  • 2、可以重復(fù)、一次性、穩(wěn)定的執(zhí)行任務(wù)。包括在設(shè)備重啟之后都能繼續(xù)任務(wù)。
  • 3、可以定義不同工作任務(wù)的銜接關(guān)系。比如設(shè)定一個(gè)任務(wù)接著一個(gè)任務(wù)。

總之,它是后臺(tái)執(zhí)行任務(wù)的一大利器。

參考

https://developer.android.google.cn/guide/components/services#Lifecycle

http://gityuan.com/2017/03/10/job_scheduler_service/

本文轉(zhuǎn)載自微信公眾號(hào)「碼上積木」,作者碼上積木。轉(zhuǎn)載本文請(qǐng)聯(lián)系碼上積木公眾號(hào)。


名稱欄目:從Service到WorkManager
文章鏈接:http://m.5511xx.com/article/cosigcd.html