我正在尝试为定期后台操作实现WorkManager
。当我试图在Handler
中使用Worker
时,我遇到了一个常见的错误。我知道错误是说我需要调用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
类的构造函数,并且你已经为你的构造函数添加了参数时,有几种方法可以为你的Looper
提供Handler
,就像下面建议的方法一样。
Looper
的构造函数:
TimeOutHandler(final SyncWorker service, Looper looper) {
super(looper);
mMainWeakReference = new WeakReference<>(service);
}
并初始化如下:
TimeOutHandler handler = new TimeOutHandler(service, Looper.getMainLooper());
Looper
传递给主构造函数:
TimeOutHandler(final SyncWorker service) {
super(Looper.getMainLooper());
mMainWeakReference = new WeakReference<>(service);
}
所以调用super()初始化父(超)类的构造函数&在我们的例子中,我们将Looper
作为参数传递给super将使用构造函数Handler(Looper looper)
初始化Handler,该构造函数之前是Handler()
(空或默认构造函数)。
注意:问题是Handler类有多个构造函数,其中一个接受Looper
,用于将Handler
切换到提供的特定线程。
请记住,即使您成功实现了Handler,您的代码也无法按预期工作。一旦从Worker类返回结果,您的进程就有资格停止。你真正想要的是一个ListenableWorker,并在你完成异步计算后完成你的ListenableFuture。