簡體   English   中英

如何在不阻塞的情況下從單獨的線程更新 UI 線程?

[英]How to update UI thread from a separate thread without blocking it?

我知道這種類型的問題在網上有幾個答案,但我想我無法理解某些部分。
我制作了一個 Android 應用程序,它將讀取用戶指定的文件並在TextView顯示內容。 為了處理大文件,我將文件讀取任務分離到一個單獨的線程上。 這是MainActivity.java文件中的代碼:

package com.mapsup.fileviewer;

import android.Manifest;
import android.app.Activity;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;

public class MainActivity extends Activity {

    EditText path;
    TextView contents;
    String file_path;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        path = findViewById(R.id.path);
        contents = findViewById(R.id.contents);
    }

    private void checkPermission() {
        if (this.checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
            this.requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 1);
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == 1) {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                Toast.makeText(getApplicationContext(), "Permission was granted", Toast.LENGTH_SHORT).show();
            } else {
                Toast.makeText(getApplicationContext(), "Permission was denied\nApplication cannot work\nPlease enable permission in settings", Toast.LENGTH_SHORT).show();
            }
        }
    }

    public void display(View view) {
        checkPermission();
        file_path=path.getText().toString();
        contents.setText("");
        Thread t=new Thread(new Reader());
        t.start();
    }

    class Reader implements Runnable {
        public void run() {
            try {
                File f=new File(file_path);
                BufferedReader br=new BufferedReader(new FileReader(f));
                String line;
                while ((line=br.readLine())!=null) {
                    final String finalLine = line;
                    contents.post(new Runnable() {
                        @Override
                        public void run() {
                            contents.append(finalLine +"\n");
                        }
                    });
                }
            } catch (final IOException e) {
                contents.post(new Runnable() {
                    @Override
                    public void run() {
                        contents.setText(e.getMessage());
                    }
                });
            }
        }
    }
}

但是,不知何故,UI 線程在讀取大文件時仍然被阻塞。 我做錯了什么,從不同線程與 UI 線程通信的正確方法是什么?

您可以使用runOnUiThread()方法來確保您的代碼塊在Main線程上執行。

runOnUiThread(new Runnable() {

                        @Override
                        public void run() {

                      // write your code to run on Main Thread

                       }
                    });

您可以從某個工作線程調用此方法,例如:

    class Reader implements Runnable {
        public void run() {
            try {
                File f=new File(file_path);
                BufferedReader br=new BufferedReader(new FileReader(f));
                String line;
                while ((line=br.readLine())!=null) {
                    final String finalLine = line;
                    contents.post(new Runnable() {
                        @Override
                        public void run() {

                            runOnUiThread(new Runnable() {

                            @Override
                            public void run() {

                          contents.append(finalLine +"\n"); // will run on UI thread

                           }
                        });

                        }
                    });
                }
            } catch (final IOException e) {
                contents.post(new Runnable() {
                    @Override
                    public void run() {

                        runOnUiThread(new Runnable() {

                            @Override
                            public void run() {

                          contents.setText(e.getMessage()); // will run on UI thread

                           }
                        });

                    }
                });
            }
        }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM