观心静

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

问题描述

  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

posted on 2022-03-01 17:28  观心静  阅读(1762)  评论(0编辑  收藏  举报