Android Java - 在For循环中使用处理程序

时间:2014-03-16 12:51:38

标签: java android multithreading handler

我有一个for循环,它调用一个函数来下载文件。 每次调用该函数时,文件的标题都显示在TextView中。 问题是文件被下载但UI冻结了,只有在文件下载完成后才更新UI,并且只显示最后一个文件的最后一个标题。

for(int i=0; i < Titles.size(); i++){

    downloading.setText("Downloading: "+Titles.get(i));
    if(!Utils.downloadFile(Mp3s.get(i))){
        downloading.setText("ERROR Downloading: "+Titles.get(i));

    }

}

我知道我必须使用Handler或Thread来解决这个问题。 但我不确定如何实施它。

1 个答案:

答案 0 :(得分:1)

您可以尝试使用Activity.runOnUiThread() - 例如:

// Move download logic to separate thread, to avoid freezing UI.
new Thread(new Runnable() {
  @Override
  public void run() {
    for(int i=0; i < Titles.size(); i++) {
      // Those need to be final in order to be used inside 
      // Runnables below.
      final String title = Titles.get(i);

      // When in need to update UI, wrap it in Runnable and
      // pass to runOnUiThread().
      runOnUiThread(new Runnable() {
        @Override
        public void run() {
          downloading.setText("Downloading: "+title);
        }
      });

      if(!Utils.downloadFile(Mp3s.get(i))) {
        runOnUiThread(new Runnable() {
          @Override
          public void run() {
            downloading.setText("ERROR Downloading: "+title);
          }
        });
    }
  }
}).start();

那是非常冗长的(是的,Java!),而且在我看来,不太可读。

另一种解决方案是使用AsyncTask,它具有方便的onProgressUpdate()方法,旨在为长时间运行的任务更新UI。它可能看起来像:

public class DownloadTask extends AsyncTask<URL, String, Void> {
  // This method will be run off the UI thread, no need to 
  // create separate thread explicitely.
  protected Long doInBackground(URL... titles) {
    for(int i=0; i < titles.length; i++) {
      publishProgress("Downloading " + titles[i]);
      if(!Utils.downloadFile(Mp3s.get(i))) {
        publishProgress("ERROR Downloading: " + titles[i]);
      }
    }
  }

   // This method will be called on the UI thread, so
   // there's no need to call `runOnUiThread()` or use handlers.
   protected void onProgressUpdate(String... progress) {
     downloading.setText(progress[0]);
   }
}

(请注意上面的代码是手写的未编译的,所以它可能是错误的,但它应该让你知道如何从这里开始。