我怎样才能修复这段代码中的废弃警告?另外,是否有其他的选择来做这件事?
Handler().postDelayed({
context?.let {
//code
}, 3000)
![]() |
小眼睛的葡萄 · JS针对浏览器窗口关闭事件的监听方法_js监 ...· 1 月前 · |
![]() |
腹黑的铅笔 · ASP.NET Core Blazor ...· 4 周前 · |
![]() |
坐怀不乱的啄木鸟 · 福州地铁最新进展!涉及2号线、4号线、6号线 ...· 1 月前 · |
![]() |
火星上的西瓜 · 桃園市青溪國中青少棒隊 - 台灣棒球維基館· 5 月前 · |
![]() |
淡定的炒饭 · 常宁市第二中学_百度百科· 10 月前 · |
![]() |
刀枪不入的领结 · 时下热映电影《女鬼桥》,背后原型比剧情更可怖 ...· 1 年前 · |
![]() |
俊逸的茶壶 · 全能千金燃翻天一口气看完 - 抖音· 1 年前 · |
我怎样才能修复这段代码中的废弃警告?另外,是否有其他的选择来做这件事?
Handler().postDelayed({
context?.let {
//code
}, 3000)
java
android
kotlin
android-handler
Bolt UIX
发布于
2020-04-04
20
个回答
Nikunj Paradva
发布于
2022-06-07
已采纳
0
人赞同
只有无参数的构造函数被弃用,现在更倾向于在构造函数中通过
Looper
方法指定
Looper.getMainLooper()
。
Use it for Java
new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
@Override
public void run() {
// Your Code
}, 3000);
Use it for Kotlin
Handler(Looper.getMainLooper()).postDelayed({
// Your Code
}, 3000)
直截了当...
UNREAL
:
什么是getMainLooper()?
@UNREAL 返回应用程序的主循环器,它生活在应用程序的主线程中。
developer.android.com/reference/android/os/...
Son Truong
发布于
2022-06-07
0
人赞同
从API级别30开始,有2个构造函数被废弃了。
谷歌解释了下面的原因。
在构建处理程序时隐含地选择一个Looper
处理程序构建过程中隐式地选择Looper,可能会导致操作被悄悄丢失的错误
丢失(如果处理程序不期望有新的任务并退出)、崩溃
(崩溃(如果有时在一个没有Looper的线程上创建处理程序
活动的线程上创建处理程序),或者竞赛条件,即处理程序所关联的线程
与之相关的线程不是作者所预期的。相反,使用一个执行器或
明确指定Looper,使用Looper#getMainLooper,{link
android.view.View#getHandler},或类似的方法。如果隐含的线程
本地行为是为了兼容,请使用new
Handler(Looper.myLooper(), callback)来让读者明白。
Solution 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.
Kotlin
// 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.
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 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)
Note:记住在使用后要关闭执行器。
backgroundExecutor.shutdown(); // or backgroundExecutor.shutdownNow();
3.在一个后台线程中执行代码 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.
Kotlin
// 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.
Solution 2:通过使用以下构造函数之一明确指定一个Looper。
Handler(Looper, Handler.Callback)
1.在主线程中执行代码
1.1.带循环器的处理程序
Handler mainHandler = new Handler(Looper.getMainLooper());
Kotlin
val mainHandler = Handler(Looper.getMainLooper())
1.2带循环器的处理程序 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;
Kotlin
val mainHandler = Handler(Looper.getMainLooper(), Handler.Callback {
// Your code logic goes here.
2.在一个后台线程中执行代码
2.1.带循环器的处理程序
// 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());
Kotlin
// 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.带循环器的处理程序 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;
Kotlin
// 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.
Note:记得使用后要松开线。
handlerThread.quit(); // or handlerThread.quitSafely();
3.在一个后台线程中执行代码 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;
Kotlin
// 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 {
madhu527
:
真棒的东西!欢呼声
天才!!!最佳答案
Nicolas Jafelle
发布于
2022-06-07
0
人赞同
如果你想避免Kotlin中的空检查(
?
或
!!
),你可以使用
Looper.getMainLooper()
,如果你的
Handler
正在处理一些与UI相关的事情,像这样。
Handler(Looper.getMainLooper()).postDelayed({
Toast.makeText(this@MainActivity, "LOOPER", Toast.LENGTH_SHORT).show()
}, 3000)
注意:如果你使用片段,请使用requireContext()
而不是this@MainActivity
。
Gabe Sechan
发布于
2022-06-07
0
人赞同
废弃的函数是处理程序的构造函数。 使用
Handler(Looper.myLooper()) .postDelayed(runnable, delay)
代替
这在Kotlin中不起作用,因为
Looper.myLooper()
会返回一个
Looper?
(可能为空值)。
@EllenSpertus 然后添加一个空值检查,或者使用Looper.myLooper()!!,如果它是空的,就会抛出一个NPE。 如果你在一个有循环器的线程上,它将返回非空值。 如果不是,它将返回null,在任何语言中都应该抛出一个异常。
Francesc
发布于
2022-06-07
0
人赞同
Consider using coroutines
scope.launch {
delay(3000L)
// do stuff
Inside
Activity
or
Fragment
:
lifecycleScope.launch { delay(3000L) }
Shaon
发布于
2022-06-07
0
人赞同
使用生命周期范围,这就更容易了。在活动或片段中。
lifecycleScope.launch {
delay(2000)
// Do your stuff
或使用处理程序
Handler(Looper.myLooper()!!)
Nguyen Thanh Son
发布于
2022-06-07
0
人赞同
我有
3 solutions
:
Specify the Looper explicitly:
Handler(Looper.getMainLooper()).postDelayed({
// code
}, duration)
Specify the implicit thread local behavior:
Handler(Looper.myLooper()!!).postDelayed({
// code
}, duration)
using Thread
:
Thread({
Thread.sleep(3000)
} catch (e : Exception) {
throw e
// code
}).start()
Dinith Rukshan Kumara
发布于
2022-06-07
0
人赞同
Handler()
and
Handler(Handler.Callback callback)
constructors are deprecated. Because those can leads to bugs & crashes. Use Executor or Looper explicitly.
对于Java
Handler handler = new Handler(Looper.getMainLooper());
handler.postDelayed(new Runnable() {
@Override
public void run() {
//do your work here
}, 1000);
Muhammad Nasir Aziz
发布于
2022-06-07
0
人赞同
use this
Looper.myLooper()?.let {
Handler(it).postDelayed({
//Your Code
},2500)
ajithvgiri
发布于
2022-06-07
0
人赞同
使用Executor而不是handler来获取更多信息
Executor
.
为了实现后延迟,使用
ScheduledExecutorService
。
ScheduledExecutorService worker = Executors.newSingleThreadScheduledExecutor();
Runnable runnable = () -> {
public void run() {
// Do something
worker.schedule(runnable, 2000, TimeUnit.MILLISECONDS);
iFarbod
:
这并不是一个糟糕的答案,事实上,即使是
google recommends this
.
user2168735
发布于
2022-06-07
0
人赞同
import android.os.Looper
import android.os.Handler
inline fun delay(delay: Long, crossinline completion: () -> Unit) {
Handler(Looper.getMainLooper()).postDelayed({
completion()
}, delay)
delay(1000) {
view.refreshButton.visibility = View.GONE
Faizan Haidar Khan
发布于
2022-06-07
0
人赞同
如果你在处理程序和Runnable中使用Variable,那么就像这样使用。
private Handler handler;
private Runnable runnable;
handler = new Handler(Looper.getMainLooper());
handler.postDelayed(runnable = () -> {
// Do delayed stuff here
handler.postDelayed(runnable, 1000);
}, delay);
你还需要删除onDestroy()中的回调。
@Override
public void onDestroy() {
super.onDestroy();
if (handler != null) {
handler.removeCallbacks(runnable);
Abdul Mateen
发布于
2022-06-07
0
人赞同
Coroutines Kotlin
private val SPLASH_SCREEN_TIME_OUT_CONST: Long = 3000
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_splash)
window.setFlags(
WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN
GlobalScope.launch {
delay(SPLASH_SCREEN_TIME_OUT_CONST)
goToIntro()
private fun goToIntro(){
startActivity(Intent(this, IntroActivity::class.java))
finish()
Cagdas
:
我认为GlobalScope与处理程序之间没有区别。GlobalScope不知道生命周期(除了应用程序的过程)。在我看来,根据GlobalScope,生命周期范围或自定义范围是更方便的方式。
nmahnic
发布于
2022-06-07
0
人赞同
在Kotlin中使用这种结构是一个好主意
companion object Run {
fun after(delay: Long, process: () -> Unit) {
Handler(Looper.getMainLooper()).postDelayed({
process()
}, delay)
后来被称为
Run.after(SPLASH_TIME_OUT) {
val action = SplashFragmentDirections.actionSplashFragmentToLogin()
v.findNavController().navigate(action)
jamescodingnow
发布于
2022-06-07
0
人赞同
Java答案
我写了一个方法,可以轻松使用。你可以在你的项目中直接使用这个方法。
延迟时间Millis
可以是2000,这意味着这段代码将运行
之后
2 seconds.
private void runJobWithDelay(int delayTimeMillis){
new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
@Override
public void run() {
//todo: you can call your method what you want.
}, delayTimeMillis);
KNOX.C
发布于
2022-06-07
0
人赞同
根据该文件(
https://developer.android.com/reference/android/os/Handler#Handler()
):
在处理程序构建过程中隐含地选择一个Looper可能会导致一些错误,如操作被悄悄地丢失(如果处理程序不期望新的任务并退出),崩溃(如果处理程序有时在没有Looper活动的线程上创建),或竞赛条件,即处理程序所关联的线程不是作者预期的。相反,使用Executor或明确指定Looper,使用Looper#getMainLooper,{link android.view.View#getHandler},或类似的方法。如果为了兼容需要隐含的线程本地行为,使用new Handler(Looper.myLooper())来向读者说明。
我们应该停止使用没有Looper的构造函数,而是指定一个Looper。
Abdhi P
发布于
2022-06-07
0
人赞同
我通常使用这个
Code:
Handler(Looper.myLooper() ?: return).postDelayed({
// Code what do you want
}, 3000)
Screenshot:
matrixmike
发布于
2022-06-07
0
人赞同
处理程序()等代码是由Android Studio 4.0.1生成的,比如说,当一个全屏活动从头开始创建时。我知道我们被鼓励使用Kotlin,我也是这样做的,但我不时地使用样本项目来获得一个想法。
奇怪的是,当AS实际生成代码时,我们却受到AS的责备。仔细检查错误并修复它们可能是一个有用的学术活动,但也许AS可以为我们这些爱好者生成新的干净的代码......