处理程序(Handler.Callback)已弃用
Handler(Handler.Callback) is deprecated
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 个构造函数被弃用。
Google下面解释原因。
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: 使用 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 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;
}
});
在Java个文件中使用,
Handler handler = new Handler(Looper.getMainLooper());
handler.postDelayed(new Runnable() {
@Override
public void run() {
//Code here
}
}, 2000);
在 Kotlin 文件中使用它,
Handler(Looper.getMainLooper()).postDelayed({
// Code here
}, 2000)
在Kotlin中,如果使用Handler
和Runnable
,只需添加一个键:
之前
private var handler: Handler = Handler()
之后
private var handler: Handler = Handler(Looper.getMainLooper())
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 个构造函数被弃用。
Google下面解释原因。
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: 使用 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 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;
}
});
在Java个文件中使用,
Handler handler = new Handler(Looper.getMainLooper());
handler.postDelayed(new Runnable() {
@Override
public void run() {
//Code here
}
}, 2000);
在 Kotlin 文件中使用它,
Handler(Looper.getMainLooper()).postDelayed({
// Code here
}, 2000)
在Kotlin中,如果使用Handler
和Runnable
,只需添加一个键:
之前
private var handler: Handler = Handler()
之后
private var handler: Handler = Handler(Looper.getMainLooper())