Android's AsyncTask: multiple params, returning values, waiting

吃可爱长大的小学妹 提交于 2020-01-07 04:23:06

问题


I have been looking at how to implement Android's AsyncTask class for some time now. Basically, I want it to do the classic scenario: simply animate an indefinite loading wheel while I make a network call. However, in practice I'm having some issues getting this to work the way I want.

I have code that looks like this currently: (before my desired AsyncTask implementation)

 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);

I want to be able to reuse my AsyncTask call to pass data to it, it makes a network call, and then returns me data that I can then process as I wish, like I do above.

Now - this works perfect, except of course the app appears to "hang" with no loading. In comes AsyncTask. Maybe I just don't quite "get it" yet - but how do I return data OUTSIDE of the AsyncTask so that doStuffToUI() etc can use it?

Ultimately, I'd like it if I could use the AsyncTask similar to this:

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

Am I going about this right? Is this how it should be/can be done? Here's my AsyncTask class below, shortened for brevity.

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();
    }
 }

Any help is appreciated, thanks a lot in advance. I'm happy to clarify if needed.


回答1:


doStuff(result); this shouldn't execute until the AsyncTask is done

then you will need to use AsyncTask.get() which make Waits if necessary for the computation to complete, and then retrieves its result.

because calling of AsyncTask.get() freeze main UI thread until doInBackground execution is not complete then u will need to use Thread to avoid freezing of UI and runOnUiThread for updating Ui elements after AsyncTask execution complete.

Example :-

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();
}



回答2:


Make a reusable async task with default onPostExecute implementation and then override default implementation for every call:

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
        }
    }

Execute your async task:

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();


来源:https://stackoverflow.com/questions/15153919/androids-asynctask-multiple-params-returning-values-waiting

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!