問題描述
WorkManager有一個特性 : 任務創建並且入隊后,app被后台清理了,任務不會執行. 但是在app重新啟動后,只要定時時間已經到達,任務就會在app啟動的時候立刻執行.
這個特性容易產生一些報錯與誤解性的問題.,比如:
1.因為異步初始化的模塊在doWork里的調用,doWork先執行並且調用未初始化的模塊導致的空指針報錯
2.因為這個特性,會出現任務突然之間多次重復執行的問題
解決報錯問題思路
這里首先要明確一個需求,你需不需要在app啟動的時候執行延遲的work任務.
如果你需要,並且你有引用正在異步初始化模塊,那么在doWork方法中就需要增加判空,判初始化,甚至捕獲異常防止出現報錯問題.
如果不需要,在app啟動后執行延遲觸發的work. 你只需要Application里增加以下代碼.
public class App extends Application { @Override public void onCreate() { super.onCreate(); /** * 取消全部任務 */ WorkManager.getInstance(this).cancelAllWork(); /** * 如果你只需要取消一部分任務,可以選擇cancelAllWorkByTag方法 */ WorkManager.getInstance(this).cancelAllWorkByTag("某個tag"); } }
在app啟動的時候Application的onCreate,依然會比doWork先執行. 因此我們可以選擇,因為app被殺掉,導致一直未觸發的Work調用取消方法,全部取消不執行.
解決多次重復執行的問題
這種問題引起,其實極有可能是一些work是在app啟動后被創建的. 但是如果你的app被反復的殺掉又啟動,就會出現多個任務同時執行的問題.
解決辦法1:
val oneTimeWorkRequest = OneTimeWorkRequest.Builder(MyWork::class.java) .setInitialDelay(20, TimeUnit.SECONDS) .addTag("zh") .build() /* * 添加tag,並且在創建的時候將相同tag先取消,在創建. */ WorkManager.getInstance(this).cancelAllWorkByTag("zh") WorkManager.getInstance(this).enqueue(oneTimeWorkRequest)
解決辦法2:
創建唯一任務解決
WorkManager.getInstance(MainActivity.this).beginUniqueWork("unique", ExistingWorkPolicy.REPLACE, oneTimeWorkRequest).enqueue();
End