无法在 WorkManager 中未调用 Looper.prepare() 的线程内创建处理程序

Can't create handler inside thread that has not called Looper.prepare() in WorkManager

我正在尝试为定期后台操作实施 WorkManager。尝试在 Worker 中使用 Handler 时遇到常见错误。我知道错误是说我需要调用 Looper.prepare() 因为我在错误的线程上但我不确定如何调用。

这是我正在使用的代码:

public class SyncWorker extends Worker {

    private static TimeOutHandler mTimeOutHandler;

    public SyncWorker(@NonNull Context context, @NonNull WorkerParameters params) {
        super(context, params);
        mTimeOutHandler = new TimeOutHandler(this);
    }

    @Override
    public Result doWork() {    
        return Result.success();
    }

    private static class TimeOutHandler extends Handler {
        private final WeakReference<SyncWorker> mMainWeakReference;

        //this is where the error is thrown
        TimeOutHandler(final SyncWorker service) {
            mMainWeakReference = new WeakReference<>(service);
        }

        @Override
        public void handleMessage(final Message msg) {
            final SyncWorker service = mMainWeakReference.get();

            if (service != null) {
                switch (msg.what) {
                    case MESSAGE_CONNECTIVITY_TIMEOUT:
                        mTimeOutHandler.removeMessages(MESSAGE_CONNECTIVITY_TIMEOUT);
                        break;
                }
            }
        }
    }
}

Handler handler = new Handler(Looper.getMainLooper());

我做了一些研究,一个建议的解决方案是使用:

Handler handler = new Handler(Looper.getMainLooper());

但我不知道如何用我扩展的方式做到这一点 Handler

当您创建了构造函数 扩展 Handler class,并且您已经为您的 构造函数添加了参数 有几种方法可以为您的 Handler 提供 Looper,就像下面建议的方法一样。

  1. 您还可以创建另一个访问 Looper 的构造函数:

    TimeOutHandler(final SyncWorker service, Looper looper) {
        super(looper);
        mMainWeakReference = new WeakReference<>(service);
    }
    

    并初始化为:

    TimeOutHandler handler = new TimeOutHandler(service, Looper.getMainLooper());
    
  2. 直接将Looper传递给主构造函数:

    TimeOutHandler(final SyncWorker service) {
        super(Looper.getMainLooper());
        mMainWeakReference = new WeakReference<>(service);
    }
    

所以调用 super() 初始化父 (super) class 的构造函数,在我们的例子中,我们通过 Looper 作为 super 的参数将使用构造函数 Handler(Looper looper) 初始化处理程序,之前是 Handler() (空或默认构造函数).

注意: 事情是 Handler class 有多个构造函数,其中一个接受 Looper 提供切换 Handler到提供的特定线程。

请记住,即使您成功实现了处理程序,您的代码也不会按预期工作。一旦您 return 从您的工作人员 class 获得结果,您的流程就有资格停止。你真正想要的是一个 ListenableWorker,并在完成异步计算后完成你的 ListenableFuture。