我试图确定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代码?

最佳答案

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

类文件: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.
  }
}

09-10 01:06