Home » Android » java – Return data from AsyncTask class

java – Return data from AsyncTask class

Posted by: admin June 15, 2020 Leave a comment

Questions:

How do I get the data from my AsyncTask? My MainActivity is calling the DataCall.getJSON function that triggers the AsyncTask but I am not sure how to get the data back to the original Activity.

MainActivity with call to DataCall that should return a string and save it in state_data

String state_data =  DataCall.getJSON(spinnerURL,spinnerContentType); 

DataCall:

public class DataCall extends Activity {
    private static final String TAG = "MyApp";


    private class DownloadWebPageTask extends AsyncTask<String, Void, String> {


        protected String doInBackground(String... urls) {
            String response = "";
            for (String url : urls) {
                DefaultHttpClient client = new DefaultHttpClient();
                HttpGet httpGet = new HttpGet(url);
                try {
                    HttpResponse execute = client.execute(httpGet);
                    InputStream content = execute.getEntity().getContent();

                    BufferedReader buffer = new BufferedReader(
                            new InputStreamReader(content));
                    String s = "";
                    while ((s = buffer.readLine()) != null) {
                        response += s;
                    }

                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            return response;
        }


        protected void onPostExecute(String result) {
            //THIS IS WHERE I NEED TO RETURN MY DATA TO THE MAIN ACTIVITY. (I am guessing)
        }

        }

    public void getJSON(String myUrlString, String contentType) {
        DownloadWebPageTask task = new DownloadWebPageTask();
        task.execute(new String[] { "http://www.mywebsite.com/" + myUrlString });

    }

}
How to&Answers:

The key for me was to create a class called URLWithParams or something because AsyncTask will allow only 1 type to be sent IN, and I needed both the URL and the params for the HTTP request.

public class URLWithParams {

    public String url;
    public List<NameValuePair> nameValuePairs;

    public URLWithParams()
    {
        nameValuePairs = new ArrayList<NameValuePair>();
    }
}

and then I send it to a JSONClient:

public class JSONClient extends AsyncTask<URLWithParams, Void, String> {
    private final static String TAG = "JSONClient";

    ProgressDialog progressDialog ;
    GetJSONListener getJSONListener;
    public JSONClient(GetJSONListener listener){
        this.getJSONListener = listener;
    }

    @Override
    protected String doInBackground(URLWithParams... urls) {
        return connect(urls[0].url, urls[0].nameValuePairs);
    }

    public static String connect(String url, List<NameValuePair> pairs)
    {
        HttpClient httpclient = new DefaultHttpClient();

        if(url == null)
        {
            Log.d(TAG, "want to connect, but url is null");
        }
        else
        {
            Log.d(TAG, "starting connect with url " + url);
        }

        if(pairs == null)
        {
            Log.d(TAG, "want to connect, though pairs is null");
        }
        else
        {
            Log.d(TAG, "starting connect with this many pairs: " + pairs.size());
            for(NameValuePair dog : pairs)
            {
                Log.d(TAG, "example: " + dog.toString());
            }
        }

        // Execute the request
        HttpResponse response;
        try {
            // Prepare a request object
            HttpPost httpPost = new HttpPost(url); 
            httpPost.setEntity(new UrlEncodedFormEntity(pairs));
            response = httpclient.execute(httpPost);
            // Examine the response status
            Log.i(TAG,response.getStatusLine().toString());

            BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent(), "UTF-8"));
            String json = reader.readLine();
            return json;

        } catch (ClientProtocolException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        return null;
    }



    @Override
    protected void onPostExecute(String json ) {
        getJSONListener.onRemoteCallComplete(json);
    }


    public interface GetJSONListener {
        public void onRemoteCallComplete(String jsonFromNet);
    }

}

Then call it from my main class like this

public class BookCatalog implements GetJSONListener {
    private final String TAG = this.getClass().getSimpleName();

    private String catalog_url = "URL";

    private void getCatalogFromServer() {

        URLWithParams mURLWithParams = new URLWithParams();
        mURLWithParams.url = catalog_url;

        try {
            JSONClient asyncPoster = new JSONClient(this);
            asyncPoster.execute(mURLWithParams);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    @Override
    public void onRemoteCallComplete(String jsonBookCatalogList) {

        Log.d(TAG, "received json catalog:");
        Log.d(TAG, jsonBookCatalogList);
    JSONObject bookCatalogResult;
    try {
        bookCatalogResult = (JSONObject) new JSONTokener(jsonBookCatalogList).nextValue();
        JSONArray books = bookCatalogResult.getJSONArray("books");

        if(books != null) {
            ArrayList<String> newBookOrdering = new ArrayList<String>();
            int num_books = books.length();
            BookCatalogEntry temp;

            DebugLog.d(TAG, "apparently we found " + Integer.toString(num_books) + " books.");
            for(int book_id = 0; book_id < num_books; book_id++) {
                JSONObject book = books.getJSONObject(book_id);
                String title = book.getString("title");
                int version = book.getInt("price");
            }
        }

    } catch (JSONException e) {
        e.printStackTrace();
    } 

    }


}

Answer:

modify your AsyncTask as below:

public class GetData extends AsyncTask<String, Void, String>
{
    DataDownloadListener dataDownloadListener;
    public GetData()
    {
        //Constructor may be parametric 
    }
    public void setDataDownloadListener(DataDownloadListener dataDownloadListener) {
        this.dataDownloadListener = dataDownloadListener;
    }
    @Override
    protected Object doInBackground(Object... param) 
    {
        // do your task...
        return null;
    }
    @Override
    protected void onPostExecute(Object results)
    {       
        if(results != null)
        {               
        dataDownloadListener.dataDownloadedSuccessfully(results);
        }
        else
        dataDownloadListener.dataDownloadFailed();
    }
    public static interface DataDownloadListener {
        void dataDownloadedSuccessfully(Object data);
        void dataDownloadFailed();
    }
}

and use it in your Activity

GetData getdata = new GetData();
getdata.setDataDownloadListener(new DataDownloadListener()
{
    @SuppressWarnings("unchecked")
    @Override
    public void dataDownloadedSuccessfully(Object data) {
    // handler result
    }
    @Override
    public void dataDownloadFailed() {
    // handler failure (e.g network not available etc.)
    }
});
getdata.execute("");

NOTE: For the people who are reading this.

Please consider this post for the best and perhaps right implementation.

Answer:

Although i disagree creating a new activity for that simple task there is

startActivityForResult()

to get data from another activity.

Check this. You can store your data to the Intent’s extras. But still if you have a large amount of data you better off write it to a file get the result from the other activity that is done downloading and then read the file.

Answer:

Serialize it and then read it. The only way I’m aware of.

Answer:

Some options:

a) Make your bean implement Serializable interface, you can then pass your bean through Intent.

b) Implement Application interface (you need to make an entry in manifest), Have setter\getter method in your Application class. You can set your bean in Application from AsyncTask and later retrieve from Activity.

Answer:

Sorry for answering so late, i think by this time you might have solved this problem. when i was searching for something else, i came across your question. I’m pasting a link here which might of some help for others.