0

一段时间以来,我一直在研究如何实现 Android 的 AsyncTask 类。基本上,我希望它完成经典场景:在我进行网络调用时简单地动画一个无限期的加载轮。但是,在实践中,我遇到了一些问题,无法按照我想要的方式工作。

我目前有这样的代码:(在我想要的 AsyncTask 实现之前)

 String result = timeConsumingNetworkCall(String someData, ArrayList stuff1);
 doStuff(result);

 String result = timeConsumingNetworkCall(String otherData, ArrayList stuff2);
 doOtherStuff(result);

 String result = timeConsumingNetworkCall(String dataAgain, ArrayList stuff3);
 doYetEvenMore(result);

我希望能够重用我的 AsyncTask 调用来将数据传递给它,它进行网络调用,然后返回我可以按照我的意愿处理的数据,就像我在上面做的那样。

现在 - 这很完美,除了应用程序似乎在没有加载的情况下“挂起”。进来了 AsyncTask。也许我还没有完全“得到它”——但我如何在 AsyncTask 之外返回数据,以便doStuffToUI()etc 可以使用它?

最终,如果我可以使用类似这样的 AsyncTask,我会很高兴:

String result = new PostToFile("function_name", keysAndValues).execute().getResult();
doStuff(result); // this shouldn't execute until the AsyncTask is done

我这样做对吗?这是应该/可以做到的吗?下面是我的 AsyncTask 类,为简洁起见缩短了。

private class PostToFile extends AsyncTask<PostToFile, Void, Void>{
    private String functionName;
    private ArrayList<NameValuePair> postKeyValuePairs;
    private String result = "";

    public PostToFile(String function, ArrayList<NameValuePair> keyValuePairs){
        functionName= function;
        postKeyValuePairs = keyValuePairs;
    }

    @Override
    protected void onPreExecute() {
        progressDialog = ProgressDialog.show(BaseActivity.getInstance(), "Loading", "Please wait...", true, false);
    }

    @Override
    protected Void doInBackground(PostToFile... params) {                       
        ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
        nameValuePairs.add(new BasicNameValuePair(FUNCTION_KEYWORD, functionName));
        for (int i = 0; i < postKeyValuePairs.size(); i++)            {
            nameValuePairs.add(postKeyValuePairs.get(i));
        }

        try{
            // ***do the POST magic.***
            result = response.toString();
        }
        catch (Exception e){
             // clean up my mess
        }

        return null;
    }

    private String getResult(){
        return result; // can I use this somehow???
    }

    @Override
    protected void onPostExecute(Void result) {
        progressDialog.dismiss();
    }
 }

任何帮助表示赞赏,非常感谢提前。如果需要,我很乐意澄清。

4

2 回答 2

1

做事(结果);这不应该在 AsyncTask 完成之前执行

那么您将需要使用 AsyncTask.get()在必要时进行等待以完成计算,然后检索其结果。

因为在执行未完成之前调用AsyncTask.get()冻结主 UI 线程, doInBackground那么您将需要使用 Thread 来避免 UI 冻结并runOnUiThread在 AsyncTask 执行完成后更新 Ui 元素。

例子 :-

public void  ThreaddoStuff(){

 Thread th=new Thread(){
    @Override
    public void run(){
      // start AsyncTask exection here
      String result = new PostToFile("function_name", 
                      keysAndValues).execute().get().getResult();

     // now call doStuff by passing result
     doStuff(result);
    }
  };
th.start();
}
于 2013-03-01T09:27:38.940 回答
1

使用默认的 onPostExecute 实现创建一个可重用的异步任务,然后为每个调用覆盖默认实现:

public static class PostToFile extends AsyncTask<Void, Void, String> {
        private String functionName;
        private ArrayList<NameValuePair> postKeyValuePairs;
        private String result = "";

        public PostToFile(String function, ArrayList<NameValuePair> keyValuePairs){
            functionName= function;
            postKeyValuePairs = keyValuePairs;
        }

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            // show progress bar
        }

        @Override
        protected String doInBackground(Void... arg0) {
            // make request and get the result
            return null; // return result
        }

        @Override
        protected void onCancelled(String result) {
            super.onCancelled(result);
            // hide progress bar
        }

        @Override
        protected void onPostExecute(String result) {
            super.onPostExecute(result);
            // hide progress bar
        }
    }

执行你的异步任务:

new PostToFile(function, keyValuePairs) {

        @Override
        protected void onPostExecute(String result) {
            super.onPostExecute(result); // this will hide a progress bar

            doStuff(result); 
        }
}.execute();

new PostToFile(otherFunction, otherKeyValuePairs) {

        @Override
        protected void onPostExecute(String result) {
            super.onPostExecute(result); // this will hide a progress bar

            doOtherStuff(result); 
        }
}.execute();
于 2013-03-01T11:02:00.810 回答