我该如何修复这段代码中的弃用警告?或者,是否有其他选项可以实现相同的功能?
我该如何修复这段代码中的弃用警告?或者,是否有其他选项可以实现相同的功能?
Handler().postDelayed({
context?.let {
//code
}
}, 3000)
我该如何修复这段代码中的弃用警告?或者,是否有其他选项可以实现相同的功能?
我该如何修复这段代码中的弃用警告?或者,是否有其他选项可以实现相同的功能?
Handler().postDelayed({
context?.let {
//code
}
}, 3000)
Looper.getMainLooper()
方法指定Looper
。
new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
@Override
public void run() {
// Your Code
}
}, 3000);
Handler(Looper.getMainLooper()).postDelayed({
// Your Code
}, 3000)
谷歌在下面解释了原因。
在Handler构造期间隐式选择一个Looper可能会导致一些bug,其中操作会被静默丢失(如果Handler不期望新任务并退出),崩溃(如果有时在没有活动的Looper的线程上创建Handler),或者竞争条件,即与Handler关联的线程不是作者预期的那个。相反,使用Executor或显式指定Looper,使用Looper#getMainLooper,{link android.view.View#getHandler}或类似方法。如果需要兼容性的隐式线程本地行为,请使用new Handler(Looper.myLooper(), callback)来明确告诉读者。
解决方案1:使用Executor
1. 在主线程中执行代码。
Java
// 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.
}
});
// Create an executor that executes tasks in the main thread.
val mainExecutor = ContextCompat.getMainExecutor(this)
// Execute a task in the main thread
mainExecutor.execute {
// You code logic goes here.
}
// 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 3 seconds.
backgroundExecutor.schedule(new Runnable() {
@Override
public void run() {
// Your code logic goes here
}
}, 3, TimeUnit.SECONDS);
Kotlin
// Create an executor that executes tasks in a background thread.
val backgroundExecutor: ScheduledExecutorService = Executors.newSingleThreadScheduledExecutor()
// Execute a task in the background thread.
backgroundExecutor.execute {
// Your code logic goes here.
}
// Execute a task in the background thread after 3 seconds.
backgroundExecutor.schedule({
// Your code logic goes here
}, 3, TimeUnit.SECONDS)
backgroundExecutor.shutdown(); // or backgroundExecutor.shutdownNow();
3. 在后台线程中执行代码,并在主线程上更新用户界面。
Java
// 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.
}
});
}
});
// Create an executor that executes tasks in the main thread.
val mainExecutor: Executor = ContextCompat.getMainExecutor(this)
// Create an executor that executes tasks in a background thread.
val backgroundExecutor = Executors.newSingleThreadScheduledExecutor()
// Execute a task in the background thread.
backgroundExecutor.execute {
// Your code logic goes here.
// Update UI on the main thread
mainExecutor.execute {
// You code logic goes here.
}
}
解决方案2:通过使用以下构造函数之一来明确指定一个 Looper。
1. 在主线程中执行代码
1.1. 使用 Looper 的 Handler
Java
Handler mainHandler = new Handler(Looper.getMainLooper());
val mainHandler = Handler(Looper.getMainLooper())
Handler mainHandler = new Handler(Looper.getMainLooper(), new Handler.Callback() {
@Override
public boolean handleMessage(@NonNull Message message) {
// Your code logic goes here.
return true;
}
});
val mainHandler = Handler(Looper.getMainLooper(), Handler.Callback {
// Your code logic goes here.
true
})
2. 在后台线程中执行代码
2.1. 带有 Looper 的 Handler
Java
// 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());
// Create a background thread that has a Looper
val handlerThread = HandlerThread("HandlerThread")
handlerThread.start()
// Create a handler to execute tasks in the background thread.
val backgroundHandler = Handler(handlerThread.looper)
2.2. 使用 Looper 和 Handler.Callback 的处理程序
Java
// 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;
}
});
// Create a background thread that has a Looper
val handlerThread = HandlerThread("HandlerThread")
handlerThread.start()
// Create a handler to execute taks in the background thread.
val backgroundHandler = Handler(handlerThread.looper, Handler.Callback {
// Your code logic goes here.
true
})
handlerThread.quit(); // or handlerThread.quitSafely();
// 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;
}
});
// Create a handler to execute code in the main thread
val mainHandler = Handler(Looper.getMainLooper())
// Create a background thread that has a Looper
val handlerThread = HandlerThread("HandlerThread")
handlerThread.start()
// Create a handler to execute in the background thread
val backgroundHandler = Handler(handlerThread.looper, Handler.Callback {
// Your code logic goes here.
// Update UI on the main thread.
mainHandler.post {
}
true
})
如果你想在 Kotlin 中避免空检查 (?
或 !!
),当你的 Handler
处理一些 UI 相关的事情时,你可以使用 Looper.getMainLooper()
,像这样:
Handler(Looper.getMainLooper()).postDelayed({
Toast.makeText(this@MainActivity, "LOOPER", Toast.LENGTH_SHORT).show()
}, 3000)
注意:如果你正在使用fragment,请使用requireContext()
,而不是this@MainActivity
。
废弃的函数是 Handler 的构造函数。请使用 Handler(Looper.myLooper()).postDelayed(runnable, delay)
代替。
Looper.myLooper()
返回一个 Looper?
(可能为空值)。 - Ellen Spertus考虑使用协程
scope.launch {
delay(3000L)
// do stuff
}
Activity
或Fragment
中:lifecycleScope.launch { delay(3000L) }
说明:这段代码使用了Kotlin协程,延迟3秒钟后执行。lifecycleScope
确保在此Activity
或Fragment
的生命周期结束时取消该协程,以避免内存泄漏和其他潜在的问题。 - Mahmudul Hasan Shohag使用生命周期作用域会更加容易,在活动或片段内。
lifecycleScope.launch {
delay(2000)
// Do your stuff
}
或使用处理程序
Handler(Looper.myLooper()!!)
我有3种解决方案:
Handler(Looper.getMainLooper()).postDelayed({
// code
}, duration)
指定隐式线程本地行为: Handler(Looper.myLooper()!!).postDelayed({
// code
}, duration)
使用 Thread
: Thread({
try{
Thread.sleep(3000)
} catch (e : Exception) {
throw e
}
// code
}).start()
Handler()
和Handler(Handler.Callback callback)
构造函数已被弃用,因为它们可能导致错误和崩溃。请明确地使用Executor或Looper。
对于Java
Handler handler = new Handler(Looper.getMainLooper());
handler.postDelayed(new Runnable() {
@Override
public void run() {
//do your work here
}
}, 1000);
使用这个
Looper.myLooper()?.let {
Handler(it).postDelayed({
//Your Code
},2500)
}
使用 Executor 而不是 handler 来获取更多信息。
要实现延迟发布,请使用 ScheduledExecutorService
:
ScheduledExecutorService worker = Executors.newSingleThreadScheduledExecutor();
Runnable runnable = () -> {
public void run() {
// Do something
}
};
worker.schedule(runnable, 2000, TimeUnit.MILLISECONDS);