简体   繁体   中英

Android AsyncTask: How to handle the return type

I am working on an Android application that executes an http POST request , and the tutorial I followed was resulting in an android.os.NetworkOnMainThreadException

The original code was something like this.

public class JSONParser {

static InputStream is = null;
static JSONObject jObj = null;
static String json = "";

// constructor
public JSONParser() {

}

public JSONObject getJSONFromUrl(String url, List<NameValuePair> params) {

    // Making HTTP request
    try {
        // defaultHttpClient
        DefaultHttpClient httpClient = new DefaultHttpClient();
        HttpPost httpPost = new HttpPost(url);
        httpPost.setEntity(new UrlEncodedFormEntity(params));

        HttpResponse httpResponse = httpClient.execute(httpPost);
        HttpEntity httpEntity = httpResponse.getEntity();
        is = httpEntity.getContent();

    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    } catch (ClientProtocolException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }

    try {
        BufferedReader reader = new BufferedReader(new InputStreamReader(
                is, "iso-8859-1"), 8);
        StringBuilder sb = new StringBuilder();
        String line = null;
        while ((line = reader.readLine()) != null) {
            sb.append(line + "\n");
        }
        is.close();
        json = sb.toString();
        Log.e("JSON", json);
    } catch (Exception e) {
        Log.e("Buffer Error", "Error converting result " + e.toString());
    }

    // try parse the string to a JSON object
    try {
        jObj = new JSONObject(json);            
    } catch (JSONException e) {
        Log.e("JSON Parser", "Error parsing data " + e.toString());
    }

    // return JSON String
    return jObj;

}
}

And this class was invoked with this line.

JSONObject json = jsonParser.getJSONFromUrl(loginURL, params);

After changing this to an AsyncTask class, the code looks like this.

class JSONParser extends AsyncTask<String, Void, JSONObject>{

static InputStream is = null;
static JSONObject jObj = null;
static String json = "";

// variables passed in:
String url;
List<NameValuePair> params;

// constructor
public JSONParser(String url, List<NameValuePair> params) {
    this.url = url;
    this.params = params;
}

@Override
protected JSONObject doInBackground(String... args) {
    // Making HTTP request
        try {
            // defaultHttpClient
            DefaultHttpClient httpClient = new DefaultHttpClient();
            HttpPost httpPost = new HttpPost(url);
            httpPost.setEntity(new UrlEncodedFormEntity(params));

            HttpResponse httpResponse = httpClient.execute(httpPost);
            HttpEntity httpEntity = httpResponse.getEntity();
            is = httpEntity.getContent();


        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }


        try {
            BufferedReader reader = new BufferedReader(new InputStreamReader(
                    is, "iso-8859-1"), 8);
            StringBuilder sb = new StringBuilder();
            String line = null;
            while ((line = reader.readLine()) != null) {
                sb.append(line + "\n");
            }
            is.close();
            json = sb.toString();
            Log.e("JSON", json);
        } catch (Exception e) {
            Log.e("Buffer Error", "Error converting result " + e.toString());
        }

        // try parse the string to a JSON object
        try {
            jObj = new JSONObject(json);            
        } catch (JSONException e) {
            Log.e("JSON Parser", "Error parsing data " + e.toString());
        }

        // return JSON String
        return jObj;
}

@Override
protected void onPostExecute(JSONObject jObj) {
    return;
}       
}

My question is, how do I return a JSONObject from this new AsyncTask class?I can see that jObj is being returned in doInBackground() , but I am not sure where it is being returned to.

What do I need to modify or how do I need to call my new JSONParser class so that it is returning a JSONObject ?

Have a look at this code, it may give you an insight as to how to deal with the parsing of JSON objects. I am just posting the onPostExecute function for now because you seemed to have all the rest figured correctly.

As for your doubt as to where the data object from the doInBackground is returned, it is automatically sent to the onPostExecute where you can further on parse it.

            @Override
    protected void onPostExecute(JSONObject result)
    {
        try
        {   
            JSONObject data = result.getJSONObject("data");
                      // whatever your JSON tag may be, in this case its data.

            if (data.isNull("data"))
            {
                      // action to handle null JSON object.
            }               
            else
            {
                JSONArray jarray = data.getJSONArray("data");   
                int len=jarray.length();
                for (int i = 0; i < jarray.length(); i++)
                {
                JSONObject obj = (JSONObject) jarray.get(i);

             String instanceName = obj.getString("instanceName");   
                        //extract data by whatever tag names you require, in this case instanceName.    
           } 
         }
} 
        catch (JSONException je)
        {
            je.printStackTrace();
            Log.d(TAG, "Error: " + je.getMessage());
        }       
    }
}

I can see that jObj is being returned in doInBackground() but I am not sure where it is being returned to.

The result of doinBackground() is received as a parameter in onPostExecute(). You are returning a json object in doinBackground() which is a parameter to onPostExecute().

@Override
protected void onPostExecute(JSONObject jObj) {
return;
} 

Usage

new JSONParser().execute("url);
class JSONParser extends AsyncTask<String, Void, JSONObject>{

   //string parameter to doInBackground()
   //JSONObject - result returned in doInBackground() received as a param in onPostExecute()
} 

You can also pass paramters to the constructor of your asynctask

 new JSONParser("url",params).execute(); 

In your asynctask;

String url;
List<NameValuePair> params;

// constructor
public JSONParser(String url, List<NameValuePair> params) {
this.url = url;
this.params = params;
}

from your doInBackground Method

@Override
protected JSONObject doInBackground(String... args) {

 return jObj;

}

your return your JsonObject to

@Override
protected void onPostExecute(JSONObject jObj) {

    // Here you get your return JsonObject
}  

An Async Task has 3 attribures

Params, the type of the parameters sent to the task upon execution.

Progress, the type of the progress units published during the background computation.

Result, the type of the result of the background computation.

The point you need to understand is that you are creating a object of Async Task Class While calling new JSONParser(loginURL, params);

The solution is that create a public result variable in your Async class and the call execute() on the object of class and then access the public object from the object.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM