Aly
Aly

Reputation: 55

Asynctask + JSON (how to get some values)


I was using JSONparser to get some values in a remote mySQL database, and this was working fine until I tested it in Android 3.0+ (Honeycomb), that has the Guardian which won't allow a process perform a networking operation on its main thread.

So I discovered I need an Asynctask: How to fix android.os.NetworkOnMainThreadException?


And tried this topics:

Get returned JSON from AsyncTask

Return JSON Array from AsyncTask

How to return data from asynctask


Well, now I know that asynctask can't return values, but I need to get this json values because I have many calls in different activities waiting for that to process and/or show the information in screen (That's why I can't do it in OnPostExecute, I guess).


Here are the classes, with some adaptations from my old JsonParser.

JSONParser.java

public class JSONParser extends AsyncTask<List<NameValuePair>, Void, JSONObject> {

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

    private static String jsonURL = "http://192.168.1.119/Server/db/json/";

    private ProgressDialog progressDialog;

    // constructor
    public JSONParser() {

    }

    @Override
    protected void onPreExecute() {
        //progressDialog = new ProgressDialog();
        progressDialog.setMessage("Aguarde...");
        progressDialog.show();
    }

    protected JSONObject doInBackground(List<NameValuePair>... params) {

        // Making HTTP request
        try {

            // defaultHttpClient
            DefaultHttpClient httpClient = new DefaultHttpClient();
            HttpPost httpPost = new HttpPost(jsonURL);
            httpPost.setEntity(new UrlEncodedFormEntity(params[0]));

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

    }


    protected void onPostExecute(JSONObject jObj) {

        result = jObj;
        progressDialog.dismiss();

    }

    public JSONObject getJson(List<NameValuePair> params){

        this.execute(params);

        return result;

    }

}


UserFunctions.java (some calls examples)

(...)

public UserFunctions(){
    JSONParser jsonParser = new JSONParser();
}

public JSONObject loginUser(String email, String password){
    List<NameValuePair> params = new ArrayList<NameValuePair>();
    params.add(new BasicNameValuePair("tag", login_tag));
    params.add(new BasicNameValuePair("email", email));
    params.add(new BasicNameValuePair("password", password));

    JSONObject json = jsonParser.getJson(params);
    //JSONObject json = jsonParser.execute(params); //doesn't return
    return json;
}
public JSONObject listProjects(String email){
    List<NameValuePair> params = new ArrayList<NameValuePair>();
    params.add(new BasicNameValuePair("tag", list_projects));
    params.add(new BasicNameValuePair("email", email));

    JSONObject json = jsonParser.getJson(params);
    return json;
}

public JSONObject setDisp(String dispID, String disp, String comment){
    List<NameValuePair> params = new ArrayList<NameValuePair>();
    params.add(new BasicNameValuePair("tag", set_disp));
    params.add(new BasicNameValuePair("dispID", dispID));
    params.add(new BasicNameValuePair("disp", disp));
    params.add(new BasicNameValuePair("comment", comment));

    JSONObject json = jsonParser.getJson(params);
    return json;
}

(...)



I tried to get passing the values to a var (JSONObject result), but no effect. (NullPointerException, I guess it try to access the var before the async finishes, because, well, it's "async")

What I need to do to get the values? Any ideas?


Many thanks guys!

Upvotes: 1

Views: 1678

Answers (1)

Jeffrey Blattman
Jeffrey Blattman

Reputation: 22637

get used to using AsyncTask, you'll need it a lot.

if you need trigger something when the task is done, broadcast. everyone that's interested (including other activities) need to register a receiver for the broadcast.

your AsyncTask,

new AsyncTask<Void,Void,List<Result>>() {
  @Override
  public List<Result> doInBackground(Void... voids) {
    final List<Result> results = ...; // get from network, or whatever
  }

  @Override
  public void onPostExecute(List<Result> results) {
    Intent intent = new Intent("com.my.action.RESULTS_READY"); // or whatever
    intent.putExtra("com.my.extra.RESULTS", new ArrayList<Result>(results);
    sendBroadcast(intent);
  }
}.execute();

now, in your other activities, register / unregister for this in onCreate() and onDestroy(). i'm assuming you want to receive the broadcast when you are paused and update some instance data.

note there are other options. for example, you could write the results to DB, then broadcast only that the results are ready and expect each interested party to retrieve them from the DB when they want. that would probably be better since it doesn't depend on the receiving the broadcast to have valid data (it's also a longer example, so i'll leave that fun to you).

Upvotes: 1

Related Questions