『壹』 JobScheler的使用和原理
JobScheler 主要用於在未來某個時間下滿足一定條件時觸發執行某項任務的情況,涉及的條件可以是網路、電量、時間等,例如執行特定的網路、是否只在充電時執行任務等。
JobScheler類負責將應用需要執行的任務發送給框架,以備對該應用Job的調度,是一個系統服務,可以通過如下方式獲取:
JobInfo是傳遞給JobScheler類的數據容器,它封裝了針對調用應用程序調度任務所需的各種約束,也可以認為一個JobInfo對象對應一個任務,JobInfo對象通過JobInfo.Builder創建。它將作為參數傳遞給JobScheler:
JobInfo.Builder是JobInfo的一個內部類,用來創建JobInfo的Builder類。
JobService是JobScheler最終回調的端點,JobScheler將會回調該類中的onStartJob()開始執行非同步任務。它是一個繼承於JobService的抽象類,做為系統回調執行任務內容的終端,JobScheler框架將通過bindService()方式來啟動該服務。因此,用戶必須在應用程序中創建一個JobService的子類,並實現其onStartJob()等回調方法,以及在androidManifest.xml中對它授予如下許可權:
注意在AndroidManifest.xml中添加許可權
當任務開始時會執行onStartJob(JobParameters params)方法,如果返回值是false,則系統認為這個方法返回時,任務已經執行完畢。如果返回值是true,那麼系統認為這個任務正要被執行,執行任務的重擔就落在了你的肩上。當任務執行完畢時你需要調用jobFinished(JobParameters params, boolean needsRescheled)來通知系統。
當系統接收到一個取消請求時,系統會調用onStopJob(JobParameters params)方法取消正在等待執行的任務。很重要的一點是如果onStartJob(JobParameters params)返回false,那麼系統假定在接收到一個取消請求時已經沒有正在運行的任務。換句話說,onStopJob(JobParameters params)在這種情況下不會被調用。
需要注意的是這個Job Service運行在主線程,這意味著你需要使用子線程,handler,或者一個非同步任務來運行耗時的操作以防止阻塞主線程。
Google官方的Sample: https://github.com/googlearchive/android-JobScheler
JobScheler是一個抽象類,它在系統框架的實現類是android.app.JobSchelerImpl
執行的入口是JobScheler.scheler,其實是調了JobSchelerImpl中的schele方法;然後再調了mBinder.schele(job)。這個mBinder就是JobSchelerService,通過Binder跨進程調用JobSchelerService。
最後調用到JobSchelerService中的schele方法:
接著發送MSG_CHECK_JOB消息,消息處理的地方是
接著執行JobHandler中的 maybeRunPendingJobsH 方法,處理相應的任務
availableContext是JobServiceContext,即ServiceConnection,這個是進程間通訊ServiceConnection,通過調用availableContext.executeRunnableJob(nextPending)方法,會觸發調用onServiceConnected,看到這里應該明白了,onServiceConnected方法中的service就是Jobservice,裡面還用了WakeLock鎖,防止手機休眠。
接著,通過Handler發消息,調用了handleServiceBoundH()方法。
從上面源碼可以看出,最終是觸發調用了JobService中的startJob方法。
從源碼看,設置的內容應用於 JobStatus ,例如網路限制
而在JobSchelerService類,相關的狀態控制在其構造函數里:
例如網路控制類ConnectivityController類
當網路發生改變時,會調用updateTrackedJobs(userid)方法,在updateTrackedJobs方法中,會判斷網路是否有改變,有改變的會調mStateChangedListener.onControllerStateChanged()方法;然後調用了JobSchelerService類中onControllerStateChanged方法:
接著也是處理MSG_CHECK_JOB 消息,和上文一樣,最終觸發調用了JobService中的startJob方法。
JobSchelerService是一個系統服務,即應該在SystemServer啟動的。閱讀SystemServer的源碼:
run 方法如下:
接著看 startOtherServices()
因此,在這里就啟動了JobSchelerService服務。
1. android 性能優化JobScheler使用及源碼分析
2. Android 9.0 JobScheler(一) JobScheler的使用
3. Android 9.0 JobScheler(二) JobScheler框架結構簡述及JobSchelerService的啟動
4. Android 9.0 JobScheler(三) 從Job的創建到執行
5. Android 9.0 JobScheler(四) Job約束條件的控制
6. 理解JobScheler機制
『貳』 《深入理解react》之調度引擎——Scheler
深入理解react
在react 18版本發布以來的近兩年時間里,許多夥伴都體驗到了並發模式帶來的爽感,createRoot()的使用讓應用有了更流暢的體驗。而這一切的核心,便是react執行流中的調度引擎——Scheler。調度,這個概念在計算機行業中廣泛存在,無論是操作系統、瀏覽器還是大型應用,都離不開調度任務的需求。Scheler,作為獨立的包,不僅可以在react中使用,更可以在任何其他庫中發揮作用,其簡潔的源碼使深入理解react成為可能。
為何需要調度器?首先是為了解決卡頓問題。在js引擎和渲染繪制都在同一線程執行的情況下,如何保證60幀的刷新頻率不被CPU密集型任務阻塞?其次,react會生成具有優先順序的任務,優先順序高的任務可能在後面產生,調度器能確保優先順序高的任務優先執行,以提升用戶體驗。
Scheler通過暴露的方法如unstable_scheleCallback,可以按照優先順序的高低順序調度任務,並保證非同步執行。在實際體驗中,我們可以創建工程來測試Scheler的執行時機,發現它會遵循優先順序順序,優先執行高優先順序任務,並在下一個宏任務中非同步執行。
源碼解析中,小根堆作為關鍵數據結構,用於維護優先順序隊列。Scheler使用小根堆來管理任務,優先順序最高的任務始終處於堆頂。優先順序的動態調整確保了任務在調度過程中的靈活排序。例如,隨著時間推移,新任務的優先順序會逐漸提高,使得原有任務在下一個周期中優先執行。
Scheler的核心邏輯在工作循環中體現,通過合理調度不同優先順序的任務,既不阻礙UI繪制,又能高效執行任務。對於大任務,用戶可以通過拆分策略,將其劃分為多個小任務,以避免阻塞UI,實現流暢的用戶體驗。
最後,Scheler在react中扮演著關鍵角色,通過合理的任務調度,確保應用流暢運行。深入理解Scheler,將為深入理解react提供堅實的基礎。關注專欄,獲取更多react相關知識。