Android-在单独的线程中从for循环更新进度条

时间:2018-11-27 04:29:42

标签: java android multithreading

我是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;
    }
}

1 个答案:

答案 0 :(得分:0)

您正在寻找AsyncTask https://developer.android.com/reference/android/os/AsyncTask

您希望将for循环放入doInBackground方法中,然后可以在onProgressUpdate中更新UI。任何花费超过几毫秒来执行或阻止UI的操作,都应在主线程之外执行。这就是为什么要将代码添加到doInBackground方法中的原因。

onPostExecutedoInBackground中的代码完成并在主线程上执行后运行。您可以在此处更新用户界面。

这是基于您的代码的一个非常简短的示例:

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);