从API级别30开始,有2个构造函数已被弃用。
谷歌以下面的解释作为原因。
在
Handler 构造期间隐式选择 Looper 可能会导致操作被静默放弃(如果 Handler 不希望新任务并退出),崩溃(如果某个处理程序有时在没有活动的 Looper 的线程上创建),或竞态条件,其中处理程序关联的线程不是作者预期的线程。相反,请使用 Executor 或明确指定 Looper,使用 Looper#getMainLooper,{link android.view.View#getHandler} 或类似工具。如果需要向后兼容性的隐式线程本地行为,请使用 new Handler(Looper.myLooper(), callback) 来让读者明确。
解决方案 1:使用 Executor
1. 在主线程中执行代码。
Executor mainExecutor = ContextCompat.getMainExecutor(this);
mainExecutor.execute(new Runnable() {
@Override
public void run() {
}
});
2. 在后台线程中执行代码
ScheduledExecutorService backgroundExecutor = Executors.newSingleThreadScheduledExecutor();
backgroundExecutor.execute(new Runnable() {
@Override
public void run() {
}
});
backgroundExecutor.schedule(new Runnable() {
@Override
public void run() {
}
}, 1, TimeUnit.SECONDS);
注意:在使用完毕后,请记得关闭执行器。
backgroundExecutor.shutdown(); // or backgroundExecutor.shutdownNow();
3. 在后台线程中执行代码并在主线程上更新用户界面。
Executor mainExecutor = ContextCompat.getMainExecutor(this);
ScheduledExecutorService backgroundExecutor = Executors.newSingleThreadScheduledExecutor();
backgroundExecutor.execute(new Runnable() {
@Override
public void run() {
mainExecutor.execute(new Runnable() {
@Override
public void run() {
}
});
}
});
解决方案2:通过使用以下构造函数之一明确指定一个Looper。
1。在主线程中执行代码
1.1。具有Looper的Handler
Handler mainHandler = new Handler(Looper.getMainLooper());
1.2 使用 Looper 和 Handler.Callback 的 Handler
Handler mainHandler = new Handler(Looper.getMainLooper(), new Handler.Callback() {
@Override
public boolean handleMessage(@NonNull Message message) {
return true;
}
});
2. 在后台线程中执行代码
2.1. 使用带有 Looper 的 Handler
// Create a background thread that has a Looper
HandlerThread handlerThread = new HandlerThread("HandlerThread");
handlerThread.start();
// Create a handler to execute tasks in the background thread.
Handler backgroundHandler = new Handler(handlerThread.getLooper());
2.2. 使用 Looper 和 Handler.Callback 的处理程序
HandlerThread handlerThread = new HandlerThread("HandlerThread");
handlerThread.start();
Handler backgroundHandler = new Handler(handlerThread.getLooper(), new Handler.Callback() {
@Override
public boolean handleMessage(@NonNull Message message) {
return true;
}
});
注意:使用完毕后请记得释放线程。
handlerThread.quit(); // or handlerThread.quitSafely();
3. 在后台线程执行代码,并在主线程上更新 UI。
Handler mainHandler = new Handler(Looper.getMainLooper());
HandlerThread handlerThread = new HandlerThread("HandlerThread");
handlerThread.start();
Handler backgroundHandler = new Handler(handlerThread.getLooper(), new Handler.Callback() {
@Override
public boolean handleMessage(@NonNull Message message) {
mainHandler.post(new Runnable() {
@Override
public void run() {
}
});
return true;
}
});