确定LoopJ何时结束所有后台连接

时间:2014-11-24 18:55:22

标签: java android arrays android-asynctask loopj

我试图确定LoopJ何时完成所有后台线程http调用。这样我就可以显示根据onSuccess方法的结果填充的数组的结果。

首先,我有一个文件名的String []。然后我循环遍历数组并创建类似的loopj连接。

 ArrayList<String> files_to_update = new ArrayList<String>(file_names.length);
 AsyncHttpClient client = new AsyncHttpClient();
    for (final String file_name : file_names) {
            client.get(BASE_URL + file_name, new AsyncHttpResponseHandler() {

            public void onStart() {
                Local_Last_Modified_Date = preferences.getString(file_name, "");
            }

            public void onSuccess(int statusCode, Header[] headers, byte[] response) {
                Server_Last_Modified_Date = headers[3].getValue();
            }

            @Override
            public void onFinish() {
                if (!Local_Last_Modified_Date.trim().equalsIgnoreCase(Server_Last_Modified_Date.trim())) {
                    files_to_update.add(file_name);
                }
            }
        });
    }

我在这里做的是比较2个日期字符串,第一个Local_Last_Modified_Date从首选项文件中提取,第二个由标题中的最后修改日期确定。然后在OnFinish()进行比较。这确定是否需要更新文件,因为服务器文件比首选日期更新。现在!我知道这不是比较日期的最佳方式,但是它可以用于我想要做的事情。

我遇到的问题是确定来自loopj的所有后台http调用已经完成,以便我现在可以在列表对话框或我选择的任何ui元素中显示数组列表的结果。我已尝试循环遍历arraylist,但因为loopj / http连接是后台线程,所以循环在所有连接完成之前执行,因此显示一个空的或未填充的完整数组。

是否存在if条件,我可以编写以确定loopj是否还没有完成所有连接的执行,以及何时执行我的ui代码?

1 个答案:

答案 0 :(得分:2)

以下代码应解决您的问题:

班级档案:UploadRunner.java

public class UploadRunner extends AsyncHttpResponseHandler implements Runnable {

  private final AsyncHttpClient client;
  private final ArrayList<String> filesList;
  private final int filesCount;
  private final Handler handler;

  private String baseURI;
  private boolean isFired;
  private int filesCounter;

  // Use in case you have no AHC ready beforehand.
  public UploadRunner(ArrayList<String> filesList) {
    this(new AsyncHttpClient(), filesList);
  }

  public UploadRunner(
    AsyncHttpClient client, 
    ArrayList<String> filesList, 
    Handler handler
  ) {
    assert null != client;
    assert null != filesList;
    assert null != handler;

    this.client = client;
    this.filesList = filesList;
    this.handler = handler;

    this.baseURI = "";
    this.filesCount = filesList.size();
    this.filesCounter = 0;
  }

  public String getBaseURI() {
    return baseURI;
  }

  public void setBaseURI(String uri) {
    baseURI = uri;
  }

  @Override
  public void run() {
    // Request to download all files.
    for(final String file : filesList) {
      client.get(baseURI + file, this);
    }
  }

  @Override
  public void onSuccess(int statusCode, Header[] headers, byte[] response) {
    // This shouldn't happen really...
    if(isFired) {
      return;
    }

    // One more file downloaded.
    filesCounter++;

    // If all files downloaded, fire the callback.
    if(filesCounter >= filesCount) {
      isFired = true;
      handler.onFinish(getLastModificationDate(headers));
    }
  }

  private String getLastModificationDate(Header[] headers) {
    // Simple mechanism to get the date, but maybe a proper one
    // should be implemented.
    return headers[3].getValue();
  }

  public static interface Handler {

    public void onFinish(String lastModificationDate);

    // TODO: Add onError() maybe?
  }
}

在这种情况下,您将上传机制封装在一个地方,并且只显示一个接口,用于在上传所有文件时回调处理程序。

典型用例:

// TODO: This typically should run in a different thread.
public class MyTask implements UploadRunner.Handler, Runnable {

  private final static BASE_URI = "http://www.example.com/";

  private final AsyncHttpClient client = new AsyncHttpClient();
  private final ArrayList<String> filesList = new ArrayList<>();

  @Override
  public void run() {
    filesList.add("1.png");
    filesList.add("2.png");
    filesList.add("3.png");
    filesList.add("4.png");
    filesList.add("5.png");

    // Create a new runner.
    UploadRunner ur = new UploadRunner(client, filesList, this);

    // Set base URI.
    ur.setBaseURI(BASE_URI);

    // Spring the runner to life.
    ur.run();
  }

  @Override
  public void onFinish(String lastModificationDate) {
    // All files downloaded, and last modification date is supplied to us.
  }
}