您好,登錄后才能下訂單哦!
這篇文章主要講解了“如何理解從Service到WorkManager的使用原理”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“如何理解從Service到WorkManager的使用原理”吧!
概念和使用
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里面進行子線程操作,這樣的結合給項目帶來的可能性就更大了。
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" />
那后臺任務該怎么辦呢?官方建議使用 JobScheduler 。
JobScheduler
任務調度JobScheduler,Android5.0被推出。(可能有的朋友感覺比較陌生,其實他也是通過Service實現的,這個待會再說)
它能做的工作就是可以在你所規定的要求下進行自動任務執行。比如規定時間、網絡為WIFI情況、設備空閑、充電時等各種情況下后臺自動運行。
所以Google讓它來替代后臺Service的一部分功能,使用:
首先,創建一個JobService:
public class MyJobService extends JobService { @Override public boolean onStartJob(JobParameters params) { return false; } @Override public boolean onStopJob(JobParameters params) { return false; } }
然后,注冊這個服務(因為JobService也是Service)
<service android:name=".MyJobService" android:permission="android.permission.BIND_JOB_SERVICE" />
最后,創建一個JobInfo并執行
JobScheduler scheduler = (JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE); ComponentName jobService = new ComponentName(this, MyJobService.class); JobInfo jobInfo = new JobInfo.Builder(ID, jobService) .setMinimumLatency(5000)// 任務最少延遲時間 .setOverrideDeadline(60000)// 任務deadline,當到期沒達到指定條件也會開始執行 .setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED)// 網絡條件,默認值NETWORK_TYPE_NONE .setRequiresCharging(true)// 是否充電 .setRequiresDeviceIdle(false)// 設備是否空閑 .setPersisted(true) //設備重啟后是否繼續執行 .setBackoffCriteria(3000,JobInfo.BACKOFF_POLICY_LINEAR) //設置退避/重試策略 .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。
WorkManager
WorkManager 是一個 API,可供您輕松調度那些即使在退出應用或重啟設備后仍應運行的可延期異步任務。
作為Jetpack的一員,并不算很新的內容,它的本質就是結合已有的任務調度相關的API,然后根據版本需求等來執行這些任務,官網有一張圖:
所以WorkManager到底能做什么呢?
1、對于一些任務約束能很好的執行,比如網絡、設備空閑狀態、足夠存儲空間等條件下需要執行的任務。
2、可以重復、一次性、穩定的執行任務。包括在設備重啟之后都能繼續任務。
3、可以定義不同工作任務的銜接關系。比如設定一個任務接著一個任務。
總之,它是后臺執行任務的一大利器。
感謝各位的閱讀,以上就是“如何理解從Service到WorkManager的使用原理”的內容了,經過本文的學習后,相信大家對如何理解從Service到WorkManager的使用原理這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。