0

We are doing lots of ( All necessary ) call on server to get user data, For this we created a common class to post data, and retrive response as JSON object. But by this our application become too slow, So we are thinking, we can retrieve data via async task.

So we modifed our code like below:-

UserFunction.java

public JSONObject getUserData(String userName,String pNumber){
    // Building Parameters
    List<NameValuePair> params = new ArrayList<NameValuePair>();
    params.add(new BasicNameValuePair("tag", getUser));
    params.add(new BasicNameValuePair("search_number_array", userName));
    params.add(new BasicNameValuePair("pNumber", pNumber));
    params.add(new BasicNameValuePair("id", pNumber));
    // getting JSON Object
    JSONParser jsonParser1=new JSONParser(loginURL, params);
  // jsonParser1.getJSONFromUrl(loginURL, params);
    jsonParser1.execute();
    Jsonresult j1=new Jsonresult();
    JSONObject json =j1.getjObjResult();
            Log.d("Response:", json.toString());   //line 45, on which getting error
    return json;
} 

JSONParse.java

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

static InputStream is = null;
static JSONObject jObj = null;
Jsonresult obj;
static String json = "";
List<NameValuePair> postparams= new ArrayList<NameValuePair>();
String URL=null;
// constructor
public JSONParser(String url, List<NameValuePair> params) {
    URL=url;
    postparams=params;
    Log.e("entered constructor", "entered in constructor ");

    // Making HTTP request


}

@Override
protected JSONObject doInBackground(String... strings) {
    Log.e("entered in bg", "entered in doinbackground ");

    try {
        // defaultHttpClient
        DefaultHttpClient httpClient = new DefaultHttpClient();
        HttpPost httpPost = new HttpPost(URL);
        httpPost.setEntity(new UrlEncodedFormEntity(postparams));

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

public void getJSONFromUrl(String url, List<NameValuePair> params) {
    URL=url;
    postparams=params;
    Log.e("entered ", "entered in getjsonurl ");

    // Making HTTP request


}
@Override
protected void onPostExecute(JSONObject result) {
    this.obj.setjObjResult(result);
}
@Override
protected void onPreExecute() {
    // TODO Auto-generated method stub
    super.onPreExecute();
}
 }

Jsonresult.java

public class Jsonresult {
 JSONObject jObjResult = null;

public JSONObject getjObjResult() {
    return jObjResult;
}

public void setjObjResult(JSONObject jObjResult) {
    this.jObjResult = jObjResult;
}
}

But we are getting this error

   java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String org.json.JSONObject.toString()' on a null object reference
        at com.keepAeye.gps.UserFunctions.getUserData(UserFunctions.java:45)

Means control is going before finishing background process. Please tell how we can fix this?

5
  • where is line 45 in UserFunctions.java? Commented Nov 7, 2016 at 7:16
  • Sorry, Question updated. BTW this is the line on which getting error Log.d("Response:", json.toString()); Commented Nov 7, 2016 at 7:18
  • the problem is you are creating new object here JSONObject json =j1.getjObjResult(); ..You need not create new object but use the old one which has been instantiated in Aysnc in onPostExc Commented Nov 7, 2016 at 7:23
  • OK. I changed my code to this JSONObject json =jsonParser1.obj.getjObjResult(); , But still getting same error. Commented Nov 7, 2016 at 7:32
  • As AsyncTask is background process, UI thread will not wait for Async to complete. It means when you called jsonParser1.execute(); then it will not wait to async to complete and your code goes to next line ie jsonParser1.obj.getjObjResult(); and finds jsonParser1.obj is null. Commented Nov 7, 2016 at 7:38

1 Answer 1

1

Well when you're calling

jsonParser1.execute();

The async task happens in another thread. Which means these lines

Jsonresult j1=new Jsonresult();
JSONObject json =j1.getjObjResult();
Log.d("Response:", json.toString());
return json;

get executed before JSONParser's doInBackground get's executed (well actually they both run in parallel).

Which means that when you call j1.getjObjResult(); your code in

@Override
protected void onPostExecute(JSONObject result) {
    this.obj.setjObjResult(result);
}

isn't even executed yet. Simple way to solve this is by having an interface like.

public interface CallBack {
    void onSuccess(JSONObject json);
}

And then implement this in your UserFunction class link

class UserFunction implements CallBack {
   ...
   @Override
   public void onSuccess(JSONObject json) {
     Log.d("Response:", json.toString());
   }
}

When you execute your AsyncTask pass a reference of your callback like so

JSONParser jsonParser1=new JSONParser(loginURL, params, this);

And maintain a reference of the callback in your AsyncTask like

CallBack mCallback;

public JSONParser(String url, List<NameValuePair> params, CallBack callBack) {
    URL=url;
    postparams=params;
    mCallback = callBack;        
    Log.e("entered constructor", "entered in constructor ");

    // Making HTTP request


}

In your onPostExecute of your AsyncTask do this.

@Override
protected void onPostExecute(JSONObject result) {
   mCallback.onSuccess(result);
}

And you should really consider using a network library for making network calls like retrofit or volley

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.