处理程序(Handler)及其回调(Handler.Callback)已被弃用。

6

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;
    }
});

3
当某个事物被弃用时,阅读文档通常有助于了解为什么以及是否有替代方法。您可以在此链接中查看有关此主题的相关信息:https://developer.android.com/reference/kotlin/android/os/Handler#%3Cinit%3E(android.os.Handler.Callback) - Slaw
这里有一个完美的答案 https://dev59.com/RlIH5IYBdhLWcg3wI5kj#63851895 - Nikunj Paradva
3个回答

16

从API级别30开始,有2个构造函数已被弃用。

谷歌以下面的解释作为原因。

在 Handler 构造期间隐式选择 Looper 可能会导致操作被静默放弃(如果 Handler 不希望新任务并退出),崩溃(如果某个处理程序有时在没有活动的 Looper 的线程上创建),或竞态条件,其中处理程序关联的线程不是作者预期的线程。相反,请使用 Executor 或明确指定 Looper,使用 Looper#getMainLooper,{link android.view.View#getHandler} 或类似工具。如果需要向后兼容性的隐式线程本地行为,请使用 new Handler(Looper.myLooper(), callback) 来让读者明确。

解决方案 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. 在后台线程中执行代码并在主线程上更新用户界面。

// 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

Handler mainHandler = new Handler(Looper.getMainLooper());

1.2 使用 Looper 和 Handler.Callback 的 Handler

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 的 Handler

// 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;
    }
});

Handler(Handler.Callback)或Handler()的旧行为是什么? - JohnyTex
@JohnyTex 由于这两个API已被标记为弃用,这意味着只要它们能够支持,Android仍然会支持它们,但在未来可能不再可用(从SDK中删除)。如果您继续使用弃用的API,则必须在更新到最新的SDK时跟踪已删除的API。只要未删除弃用的API,旧行为就不会改变。 - Son Truong
是的,但我想知道我正在使用的已弃用API的行为。在网站上,他们只说现在它已被弃用。 - JohnyTex
@JohnyTex Android不会改变您正在使用的已弃用API的任何行为,因此您不需要担心。 - Son Truong
我只是想知道它以前的工作方式,因为他们已经删除了旧行为的文档。但我在源代码中检查了一下。 - JohnyTex

0
在 Kotlin 中,如果你使用 Handler 和 Runnable,只需要加入一个关键字: before
 private var handler: Handler = Handler()

之后

private var handler: Handler = Handler(Looper.getMainLooper())

0

在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)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接