Android API30左右,Android應(yīng)用在使用傳統(tǒng)寫法使用Handler類的時候會顯示刪除線,并提示相關(guān)的方法已經(jīng)被棄用,不建議使用。
Handler handler = new Handler(){
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
switch (msg.what){
case 1:
String content = String.valueOf(msg.obj);
textView.setText(content);
break;
}
}
};
Android studio中的顯示和建議:
看下官方API關(guān)于此處的解釋:
?簡要說就是如果在實例化Handler的時候不提供Looper, 可能導(dǎo)致操作丟失(Handler 沒有預(yù)估到新任務(wù)并已退出)、App崩潰的bug(Handler有時候創(chuàng)建一個線程,但沒有運行的Looper),亦或者race情況下,造成處理錯誤。
所以作者棄用了這部分內(nèi)容。
那以后如何用Handler,或者相關(guān)功能挺好用的,有沒有替代功能呢?
通常,Android 應(yīng)用程序使用主線程來處理 UI 任務(wù)和輸入事件。因此,在此主線程上執(zhí)行任何長時間運行的任務(wù)都可能導(dǎo)致應(yīng)用程序凍結(jié)和無響應(yīng)。 該主線程將 UI 事件或消息收集到隊列 ( MessageQueue) 中,然后使用Looper類的實例對其進行處理。默認情況下,主線程已經(jīng)準備好了Looper 。
但意外總是有的,那應(yīng)該怎么處理?
1。仍然用Handler
棄用的不是Handler, 而上Handler的兩個構(gòu)造方法:
Handler()
Handler(Handler.Callback)
上面兩個構(gòu)造方法在某些情況下會發(fā)生棄用理由里面的bug,但是,并不是整個Handler類被棄用了,還可以用其他的構(gòu)造方法來構(gòu)造Handler對象。
安卓建議采用如下方法來替代:
- 使用?Executor
- 明確指定Looper 。
使用Looper.getMainLooper()定位并
使用主線程的Looper- 如果又想在其他線程,又想要不出bug,請使用
new Handler(Looper.myLooper(), callback) 或者?new Handler(Looper.myLooper())兩個構(gòu)造方法。
public Handler(@NonNull Looper looper) {
throw new RuntimeException("Stub!");
}
public Handler(@NonNull Looper looper, @Nullable Handler.Callback callback) {
throw new RuntimeException("Stub!");
}
2。仍然使用Handler的方法
2.1 在主線程內(nèi)運行。
val mainHandler = Handler(Looper.getMainLooper()).post {
System.out.println("Thread : " + Thread.currentThread().name)
}
/* prints
I/System.out: Thread : main */
2.2 在當前線程運行Handler
val mainHandler = Handler(Looper.myLooper()).post {
System.out.println("Thread : " + Thread.currentThread().name)
}
2.3 明確指出使用某線程的Looper
val handlerThread = HandlerThread("HandlerThread");
handlerThread.start();
val backgroundHandler = Handler(handlerThread.looper).post {
println("Thread : " + Thread.currentThread().name)
handlerThread.quitSafely();
}
/* prints
I/System.out: Thread : HandlerThread */
2.4 從主線程內(nèi)新建一個線程handler線程
// Create a handler to execute in the background thread
val backgroundHandler = Handler(handlerThread.getLooper(), Handler.Callback() {
// Your code logic goes here.
Handler(Looper.getMainLooper()).post {
System.out.println("Thread : " + Thread.currentThread().name)
// update UI
}
return true
}
})
3。使用?Executor
3.1 在主線程內(nèi)運行 Executor文章來源:http://www.zghlxwxcb.cn/news/detail-419825.html
val mainExecutor: Executor = ContextCompat.getMainExecutor(this)
// Execute a task in the main thread
mainExecutor.execute(Runnable {
// You code logic goes here.
})
3.2 新建后臺線程運行 Executor文章來源地址http://www.zghlxwxcb.cn/news/detail-419825.html
val backgroundExecutor: ScheduledExecutorService = Executors.newSingleThreadScheduledExecutor()
// Execute a task in the background thread.
backgroundExecutor.execute {
// background code
backgroundExecutor.shutdown();
}
// Execute a task in the background thread after 5 seconds.
backgroundExecutor.schedule({
// background code
backgroundExecutor.shutdown();
}, 5, TimeUnit.SECONDS)
到了這里,關(guān)于Android Handler被棄用,那么以后怎么使用Handler,或者類似的功能的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!