java - Handler(Handler.Callback) 已弃用
问题描述
Handler(android.os.Handler.Callback) 已弃用,我应该改用什么?
Handler handler = new Handler(new Handler.Callback() {
@Override
public boolean handleMessage(@NonNull Message message) {
switch(message.what) {
case READ_MESSAGE:
byte[] readBuff = (byte[]) message.obj;
String tempMessage = new String(readBuff, 0, message.arg1);
readMsg.setText(tempMessage);
break;
}
return true;
}
});
解决方案
从 API 级别 30 开始,有 2 个构造函数被弃用。
谷歌解释了下面的原因。
在 Handler 构造期间隐式选择 Looper 可能会导致操作丢失(如果 Handler 不期待新任务并退出)、崩溃(如果有时在没有 Looper 活动的线程上创建处理程序)或竞争条件的错误,与处理程序关联的线程不是作者预期的。相反,使用 Executor 或显式指定 Looper,使用 Looper#getMainLooper、{link android.view.View#getHandler} 或类似方法。如果为了兼容性需要隐式线程本地行为,请使用 new Handler(Looper.myLooper(), callback) 让读者清楚。
解决方案 1:使用Executor
1.在主线程中执行代码。
// Create an executor that executes tasks in the main thread.
Executor mainExecutor = ContextCompat.getMainExecutor(this);
// Execute a task in the main thread
mainExecutor.execute(new Runnable() {
@Override
public void run() {
// You code logic goes here.
}
});
2.在后台线程中执行代码
// Create an executor that executes tasks in a background thread.
ScheduledExecutorService backgroundExecutor = Executors.newSingleThreadScheduledExecutor();
// Execute a task in the background thread.
backgroundExecutor.execute(new Runnable() {
@Override
public void run() {
// Your code logic goes here.
}
});
// Execute a task in the background thread after 1 second.
backgroundExecutor.schedule(new Runnable() {
@Override
public void run() {
// Your code logic goes here
}
}, 1, TimeUnit.SECONDS);
注意:使用后记得关闭执行器。
backgroundExecutor.shutdown(); // or backgroundExecutor.shutdownNow();
3.在后台线程执行代码,在主线程更新UI。
// Create an executor that executes tasks in the main thread.
Executor mainExecutor = ContextCompat.getMainExecutor(this);
// Create an executor that executes tasks in a background thread.
ScheduledExecutorService backgroundExecutor = Executors.newSingleThreadScheduledExecutor();
// Execute a task in the background thread.
backgroundExecutor.execute(new Runnable() {
@Override
public void run() {
// Your code logic goes here.
// Update UI on the main thread
mainExecutor.execute(new Runnable() {
@Override
public void run() {
// You code logic goes here.
}
});
}
});
解决方案 2:使用以下构造函数之一显式指定 Looper。
1.在主线程中执行代码
1.1。带有 Looper 的处理程序
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) {
// Your code logic goes here.
return true;
}
});
2.在后台线程中执行代码
2.1。带有 Looper 的处理程序
// 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 的处理程序
// Create a background thread that has a Looper
HandlerThread handlerThread = new HandlerThread("HandlerThread");
handlerThread.start();
// Create a handler to execute taks in the background thread.
Handler backgroundHandler = new Handler(handlerThread.getLooper(), new Handler.Callback() {
@Override
public boolean handleMessage(@NonNull Message message) {
// Your code logic goes here.
return true;
}
});
注意:使用后记得松开线。
handlerThread.quit(); // or handlerThread.quitSafely();
3.在后台线程执行代码,在主线程更新UI。
// Create a handler to execute code in the main thread
Handler mainHandler = new Handler(Looper.getMainLooper());
// Create a background thread that has a Looper
HandlerThread handlerThread = new HandlerThread("HandlerThread");
handlerThread.start();
// Create a handler to execute in the background thread
Handler backgroundHandler = new Handler(handlerThread.getLooper(), new Handler.Callback() {
@Override
public boolean handleMessage(@NonNull Message message) {
// Your code logic goes here.
// Update UI on the main thread.
mainHandler.post(new Runnable() {
@Override
public void run() {
}
});
return true;
}
});
推荐阅读
- tableau-api - Tableau 接受用户输入来更改数据和仪表板
- r - 为什么在 R 中预测二进制时收到 ROCR 错误?
- pdf - 带有进一步 dvipdf 的乳胶:段落级别的书签层次结构不正确
- symfony - 哪个 Symfony 版本(3.0 或 4.0)更接近 3.4?
- javascript - 选择时更改选项的颜色
- linux - mbind:如何在所有节点上统一交错现有段?
- git - Git rebase 不会移动过去我们删除的文件
- python - 如何从 Tensorflow 中的预加载数据集中选择一个批次?
- reactjs - 反应:有条件地设置 setInterval
- openssl - PDF 签名:PKCS11_get_private_key 返回 NULL