不推荐使用Handler(Handler.Callback) [英] Handler(Handler.Callback) is deprecated
问题描述
不建议使用Handler(android.os.Handler.Callback),而是应该使用什么?
Handler(android.os.Handler.Callback) is deprecated what should I use instead?
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个构造函数.
From API level 30, there are 2 constructors are deprecated.
Google在下面解释了原因.
Google explains the reason below.
在过程中隐式选择一个弯针处理程序的构造可能会导致错误,而这些错误会静默地进行操作丢失(如果处理程序不期望新任务并退出),则崩溃(如果有时在没有Looper的线程上创建处理程序,活动)或竞争条件(与处理程序相关联的线程)与作者所期望的不一样.相反,请使用执行程序或使用Looper#getMainLooper明确指定Looper,{linkandroid.view.View#getHandler}或类似名称.如果隐式线程需要本地行为以实现兼容性,请使用newHandler(Looper.myLooper(),callback)使读者可以清楚地看到它.
Implicitly choosing a Looper during Handler construction can lead to bugs where operations are silently lost (if the Handler is not expecting new tasks and quits), crashes (if a handler is sometimes created on a thread without a Looper active), or race conditions, where the thread a handler is associated with is not what the author anticipated. Instead, use an Executor or specify the Looper explicitly, using Looper#getMainLooper, {link android.view.View#getHandler}, or similar. If the implicit thread local behavior is required for compatibility, use new Handler(Looper.myLooper(), callback) to make it clear to readers.
解决方案1:使用执行器
1..在主线程中执行代码.
1. Execute code in the main thread.
// 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..在后台线程中执行代码
2. Execute code in a background thread
// 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);
注意:请记住在使用后关闭执行程序.
Note: Remember to shut down the executor after using.
backgroundExecutor.shutdown(); // or backgroundExecutor.shutdownNow();
3..在后台线程中执行代码并更新主线程上的UI.
3. Execute code in a background thread and update UI on the main thread.
// 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.
Solution 2: Specify a Looper explicitly by using one of the following constructors.
1. Execute code in the main thread
1.1.带有Looper的处理程序
1.1. Handler with a Looper
Handler mainHandler = new Handler(Looper.getMainLooper());
1.2 带有Looper和Handler.Callback的处理程序
1.2 Handler with a Looper and a Handler.Callback
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. Execute code in a background thread
2.1.带有Looper的处理程序
2.1. Handler with a 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的处理程序
2.2. Handler with a Looper and a 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;
}
});
注意:请记住在使用后释放线程.
Note: Remember to release the thread after using.
handlerThread.quit(); // or handlerThread.quitSafely();
3..在后台线程中执行代码并更新主线程上的UI.
3. Execute code in a background thread and update UI on the main thread.
// 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;
}
});
这篇关于不推荐使用Handler(Handler.Callback)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!