使用后台线程更新 UI 时出现问题

Problem with updating UI with background thread

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 线程操作的。 但是我不明白怎么办。谁能解释一下。

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

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

这不仅仅是图像视图。

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

例如,看这段代码

 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
    }

Background operation is done from a separate thread while the ImageView is always manipulated from the UI thread.

Android 应用程序中的所有 UI 元素都在 Main thread 中工作,通常表示 UI Thread。如果您尝试在主线程下执行 long-运行ning 操作,它将冻结或 Application not 运行ning 异常将出现。所以你应该在后台线程下进行网络或数据库操作,并更新UI Thread中的ImageView等UI元素。

UI 话题 :

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

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

  • 它也是您与 Android 小部件交互的线程

可运行: 表示可以执行的命令。通常用于 运行 在不同线程中编写代码。

后台运行

 new Thread(new Runnable() {
        public void run() {
            // here the background operation happening
        }
    }).start();

View.post(Runnable) 用于从后台线程访问 UI 线程。

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

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

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

毫无疑问,您应该在 java 中为繁重的进程使用不同的线程。但是,任何与 UI 相关的更改、初始化(如视图)、动画都应在使用您的应用程序创建的 UI(主)线程中完成。

你也可以这样做:

 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/Main 线程中完成。