Android的AsyncTask:多个参数,返回值,等待

时间:2013-03-01 08:57:58

标签: java android android-asynctask

我一直在研究如何实现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的数据OUTSIDE以便doStuffToUI()等可以使用它?

最终,如果我可以使用与此类似的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();
    }
 }

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

2 个答案:

答案 0 :(得分:1)

  

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

然后你需要使用AsyncTask.get(),如果有必要使Waits完成计算,然后检索它的结果。

因为调用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();
}

答案 1 :(得分: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();