当我使用runOnUIThread thread.join不起作用时

时间:2018-02-25 23:05:19

标签: android multithreading

我正在创建一个Android应用程序,我希望当用户按下后退按钮显示快速动画然后完成当前活动时。

我正在使用以下代码执行此操作:

public void onBackPressed() {
    Thread t = new Thread(){
        @Override
        public void run() {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    animate();
                }
            });
        }
    };
    t.start();
    try {
        t.join();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    this.finish();
}

但它不起作用。

2 个答案:

答案 0 :(得分:2)

不要使用加入。使用join暂停主线程直到完成。但是,在主线程返回到Looper并处理invalidate事件之前,您无法重绘。所以整个事情都行不通 - 你的代码基本上就像你根本没有运行一个线程一样。

永远不要等待UI线程 - 这意味着不仅要睡觉,还要加入。相反,当动画结束时,你调用完成,然后在调用thread.start后返回。但是所有这些都非常复杂,因为你正在做的只是向Handler发布消息。

答案 1 :(得分:1)

  

我正在创建一个Android应用程序,我希望当用户按下后退按钮显示快速动画然后完成当前活动时。

就个人而言,我不建议这样做。可以这样想:当您在桌面Web浏览器中按BACK按钮时,如果网站决定在返回上一页之前显示广告,您会有多生气?

  

但它不起作用。

在主应用程序线程上调用

onBackPressed()。然后,您创建并start()后台线程。然后立即调用join(),阻止主应用程序线程,直到后台线程结束。

这有两个问题:

  1. 后台线程没有意义,因为你阻塞了主应用程序线程,直到后台线程完成。

  2. runOnUiThread()接受您的Runnable并安排在主应用程序线程上运行它。这不可能立即发生,因为你阻止了主应用程序线程。

  3. 您的代码具有与此相同的效果:

    public void onBackPressed() {
        runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        animate();
                    }
                });
        this.finish();
    }
    

    因此,在活动结束后才会调用animate()

    典型的解决方案是将一个侦听器附加到动画中,以便在动画完成时调用。然后,听众可以呼叫finish()。另一种解决方案是使用与预期动画运行时间匹配的值,在一定时间后使用Runnable来调度某些postDelayed()View。然后,您传递给Runnable的{​​{1}}可以致电postDelayed()

    但是,我不建议干扰BACK按钮处理。我不知道Android 7.0+多窗口环境(例如,Chrome OS设备,Samsung DeX)的用户体验是什么样的。