[英]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.