View.onClick方法休眠会ANR吗

128 阅读1分钟

在Android中,如果你在ViewOnClickListeneronClick方法里调用了Thread.sleep(100000);, 那么这里调用的Thread.sleep将直接作用于当前线程,即UI线程(主线程)

原因:

onClick方法是View.OnClickListener接口的一部分,该接口的实现方法(即你的onClick实现) 是在UI线程上调用的。因此,如果你在onClick方法内部调用了Thread.sleep, 那么你实际上是在暂停或阻塞了UI线程。

结果: 阻塞UI线程会导致应用程序无法响应用户的其他输入或界面更新请求,最终可能会触发ANR(Application Not Responding)对话框。

解决:

要避免这种情况,你应该将需要延迟执行的任务(如Thread.sleep所模拟的延迟)放在一个单独的线程中执行, 然后使用适当的机制(如HandlerActivity.runOnUiThreadView.postAsyncTask(尽管已被弃用)、 Kotlin协程等)来在需要时更新UI。

例如,你可以这样做:

public void onClick(View v) {
    new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                // 注意:这里不会阻塞UI线程
                Thread.sleep(100000); // 延迟100秒

                // 现在你处于非UI线程,不能直接更新UI
                // 你需要使用Handler或其他机制来在UI线程上执行UI更新

                // 假设你有一个Handler的实例,名为mHandler
                mHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        // 在这里更新UI
                    }
                });

            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }).start();
}

在这个例子中,Thread.sleep被放在了一个新的线程中执行,因此它不会阻塞UI线程。 然而,任何UI更新都需要通过某种方式(如使用Handler)来在UI线程上执行。