无法在 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
,就像下面建议的方法一样。
您还可以创建另一个访问 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() 初始化父 (super) class 的构造函数,在我们的例子中,我们通过 Looper
作为 super 的参数将使用构造函数 Handler(Looper looper)
初始化处理程序,之前是 Handler()
(空或默认构造函数).
注意: 事情是 Handler class 有多个构造函数,其中一个接受 Looper
提供切换 Handler
到提供的特定线程。
请记住,即使您成功实现了处理程序,您的代码也不会按预期工作。一旦您 return 从您的工作人员 class 获得结果,您的流程就有资格停止。你真正想要的是一个 ListenableWorker,并在完成异步计算后完成你的 ListenableFuture。
我正在尝试为定期后台操作实施 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
,就像下面建议的方法一样。
您还可以创建另一个访问
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() 初始化父 (super) class 的构造函数,在我们的例子中,我们通过 Looper
作为 super 的参数将使用构造函数 Handler(Looper looper)
初始化处理程序,之前是 Handler()
(空或默认构造函数).
注意: 事情是 Handler class 有多个构造函数,其中一个接受 Looper
提供切换 Handler
到提供的特定线程。
请记住,即使您成功实现了处理程序,您的代码也不会按预期工作。一旦您 return 从您的工作人员 class 获得结果,您的流程就有资格停止。你真正想要的是一个 ListenableWorker,并在完成异步计算后完成你的 ListenableFuture。