用后台线程更新UI的问题

时间:2020-06-27 16:01:39

标签: android java-threads

public void onClick(View v) {
    new Thread(new Runnable() {
        public void run() {
            // a potentially time consuming task
            final Bitmap bitmap =
                    processBitMap("image.png");
            imageView.post(new Runnable() {
                public void run() {
                    imageView.setImageBitmap(bitmap);
                }
            });
        }
    }).start();
}

我在android开发人员网站上阅读了这段代码,他们提到后台操作是通过单独的线程完成的,而ImageView始终是通过UI线程进行操作的。但是我不知道如何操作。谁能解释这个。

5 个答案:

答案 0 :(得分:0)

这不仅与图像视图有关。

每个应用程序都有其自己的特殊线程,该线程运行UI对象(例如View对象);该线程称为UI线程。只有在UI线程上运行的对象才能访问该线程上的其他对象。因为您在线程池中的线程上运行的任务不在您的UI线程上运行,所以它们无权访问UI对象。要将数据从后台线程移动到UI线程,请使用在UI线程上运行的Handler或协程。

例如,看这段代码

 GlobalScope.launch(Dispatchers.Main) { //IN THE MAIN THREAD

                var x = withContext(Dispatchers.IO) { // in IO THREAD
                    wait() //BACKGROUND WORK
                    }          

            
       time.text = x //setting text to text view in main thread not IO or any
                     //other thread
    }

答案 1 :(得分:0)

背景操作是通过单独的线程完成的,而 总是从UI线程操作ImageView。

my_script.py foo=fooval bar=barval my_script.py foo=fooval my_script.py bar=barval my_script.py bar=barval foo=fooval my_script.py 应用程序中的所有UI元素都在Android中工作,通常说Main thread。如果您尝试在主线程下进行长时间运行的操作,它将冻结或应用程序未运行异常。因此,您应该在后台线程下进行网络或数据库操作,并更新UI Thread中的UI元素,例如ImageView。

UI线程

  • 启动应用程序时,会自动创建Ui Thread

  • 它负责将事件分发到适当的小部件 这包括绘画事件。

  • 这也是您与Android小部件进行交互的线程

可运行: 表示可以执行的命令。通常用于在其他线程中运行代码。

背景操作

UI Thread

new Thread(new Runnable() { public void run() { // here the background operation happening } }).start(); 用于从后台线程访问UI线程。

View.post(Runnable)

答案 2 :(得分:0)

实际上,在大多数情况下,所有视图都是在UI或主线程中进行操作或处理的,另一个线程(也称为“后台线程”)用于长时间操作(例如网络访问或数据库),以避免阻塞主线程。 UI事件,用户会因为屏幕停止移动而感到应用程序崩溃。

在以下文档中了解更多信息: https://developer.android.com/guide/components/processes-and-threads

答案 3 :(得分:0)

毫无疑问,对于Java中的繁重进程,应该使用其他线程。但是,任何与UI更改,视图,动画之类的初始化有关的事情都应在随应用程序创建的UI(Main)线程中完成。

您也可以这样做:

 new Thread(new Runnable() {
            @Override
            public void run() {
               final Bitmap bitmap =
                    processBitMap("image.png");

               new Handler.post(new Runnable() {
                        @Override
                        public void run() {
                            imageView.setImageBitmap(bitmap);
                        }
                    });


}

Handler保证即使在另一个线程中进行后台工作,设置图像也要在UI /主线程中完成。

答案 4 :(得分:-2)

您需要从主线程更新UI。为此,请使用下面的代码段。

runOnUiThread(new Runnable(){
    @Override
    public void run(){
        // update UI elements here
    }
});