我是android的新手,没有太多的线程经验。我想创建一个实际可以实际进行的进度条。由于有一个for循环,需要处理进度条,该循环处理大约370,000个单词的数组,并将与用户输入匹配的单词附加到TextView。根据用户输入的精确度,此过程可能需要1到10秒。鉴于进度条必须在单独的线程上运行,是否有办法从forloop内部更新进度?
这是带有上述forloop的方法(第15行设置了一个值,该值可用于更新进度条,而第16行则假设更新了progressBar):
public void matchWords(char[] exLettersArray, String word, String[] array, ProgressBar progressBar) {
char[] guessWordChars;
char[] curWordChars;
int wordLength = word.length();
guessWordChars = word.toCharArray();
boolean matches = true;
char unknown = '-';
TextView generatedList = findViewById(R.id.generated_list);
generatedList.setMovementMethod(new ScrollingMovementMethod());
int progress;
for (int i = 0; i < array.length; i++) { //Iterates through every word in the array
progress = ((i + 1) / array.length) * 100; //Convert to %
//progressBar.setProgress(progress);
if(array[i].length() == wordLength) {
curWordChars = array[i].toCharArray();
for(int j = 0; j < wordLength && matches == true; j++) { //Iterates through every character in a word
for(int k = 0; k < exLettersArray.length; k++) { //Iterates through all letters to be excluded
if(curWordChars[j] == exLettersArray[k]) { //Makes sure that the current word does not contain exLetter
matches = false;
}
}
if(guessWordChars[j] == unknown) {
//System.out.println("found unknown variable at index " + j);
for(int q = 0; q < wordLength; q++) {
if(curWordChars[j] == guessWordChars[q]) { //Makes sure that already known letters are not used for unknown letters
matches = false;
}
}
}
else {
if(guessWordChars[j] == curWordChars[j]) {
//System.out.println(array[i] + " passed comparison of element " + j + " flag is " + matches);
}
else {
matches = false;
//System.out.println("guessWord char " + guessWordChars[j] + " != " + "curWordChars " + curWordChars[j] + " set flag to " + matches );
}
}
}
if(matches == true) {
generatedList.append(array[i]);
generatedList.append("\n");
}
}
matches = true;
}
}
答案 0 :(得分:0)
您正在寻找AsyncTask https://developer.android.com/reference/android/os/AsyncTask。
您希望将for
循环放入doInBackground
方法中,然后可以在onProgressUpdate
中更新UI。任何花费超过几毫秒来执行或阻止UI的操作,都应在主线程之外执行。这就是为什么要将代码添加到doInBackground
方法中的原因。
onPostExecute
在doInBackground
中的代码完成并在主线程上执行后运行。您可以在此处更新用户界面。
这是基于您的代码的一个非常简短的示例:
private static class MatchWordsTask extends AsyncTask<String[], Integer, Boolean> {
private WeakReference<ProgressBar> mProgressBar;
private String[] mArray;
MatchWordsTask(ProgressBar progressBar, String[] array) {
mProgressBar = new WeakReference<ProgressBar>(progressBar);
mArray = array;
}
protected Boolean doInBackground(String[]... arrays) {
for (int i = 0; i < mArray.length; i++) {
publishProgress(((i + 1) / mArray.length) * 100);
try {
Thread.sleep(1000);
} catch(Exception e) {
e.printStackTrace();
}
}
return true;
}
protected void onProgressUpdate(Integer... progress) {
mProgressBar.get().setProgress(progress[0]);
}
protected void onPostExecute(Boolean matches) {
Log.d(TAG, "Matches: " + matches);
}
}
您将像这样执行此AsyncTask:
String[] array = new String[]{"This", "is", "an", "array", "of", "words"};
new MatchWordsTask(progressBar, array).execute(array);