无法在未在WorkManager中调用Looper.prepare()的线程内创建处理程序
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了无法在未在WorkManager中调用Looper.prepare()的线程内创建处理程序相关的知识,希望对你有一定的参考价值。
我正在尝试为定期后台操作实现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。
以上是关于无法在未在WorkManager中调用Looper.prepare()的线程内创建处理程序的主要内容,如果未能解决你的问题,请参考以下文章
CountDownTimer:“无法在未调用 Looper.prepare() 的线程内创建处理程序”
无法在未调用 Looper 准备的线程内创建处理程序 [重复]
无法在未调用 Looper.prepare()3 的线程内创建处理程序