0

I'm using HttpURLConnection to parse the jsonResponse. It does a great work most of the time. But sometimes, it is giving 'java.lang.String java.lang.String.toString()' on a null object reference error in this line: "jsonResponse = new JSONObject(response.toString());" and then the app crashes. I'm using try and catch here but still the app crashes. why the app is crashing btw? How can I solve this problem?

Error log

11-06 16:31:59.312 21887-21887/? E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.zzz.com.zz, PID: 21887
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String java.lang.String.toString()' on a null object reference
   at com.zzz.com.zz.jobschedulers.MainActivity$LoginTask.onPostExecute(MainActivity.java:761)
   at com.zzz.com.zz.jobschedulers.MainActivity$LoginTask.onPostExecute(MainActivity.java:664)
   at android.os.AsyncTask.finish(AsyncTask.java:651)
   at android.os.AsyncTask.access$500(AsyncTask.java:180)
   at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:668)
   at android.os.Handler.dispatchMessage(Handler.java:102)
   at android.os.Looper.loop(Looper.java:148)
   at android.app.ActivityThread.main(ActivityThread.java:7409)
   at java.lang.reflect.Method.invoke(Native Method)
   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)

code

class LoginTask extends AsyncTask<String, Void, String> {
    @Override
    protected void onPreExecute() {

    }

    protected String doInBackground(String... params) {
        URL url;
        String response = "";
        try {
            url = new URL("http://zzzz.com");

            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setReadTimeout(25000);
            conn.setConnectTimeout(25000);
            conn.setRequestMethod("POST");
            conn.setDoInput(true);
            conn.setDoOutput(true);


            OutputStream os = conn.getOutputStream();
            BufferedWriter writer = new BufferedWriter(
                    new OutputStreamWriter(os, "UTF-8"));
            HashMap<String, String> h1 = new HashMap<String, String>();


            h1.put("username", email);
            h1.put("password", password);
            writer.write(getPostDataString(h1));

            writer.flush();
            writer.close();
            os.close();
            int responseCode = conn.getResponseCode();
            Log.e("upload gps", "uploaded");
            if (responseCode == HttpsURLConnection.HTTP_OK) {
                String line;
                BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
                while ((line = br.readLine()) != null) {
                    response += line;
                }
                return response;
            } else {
                response = "";

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


    @Override
    protected void onPostExecute(String response) {

        JSONObject jsonResponse = null;
        try {
            jsonResponse = new JSONObject(response.toString());
            status = jsonResponse.getString("status");
            responseMsg = jsonResponse.getString("message");

            if (status.equalsIgnoreCase("true")) {
                Log.e("response ", response + "");

                JSONObject jsonResponse1 = jsonResponse.getJSONObject("data");
                String userId = jsonResponse1.getString("user_id");
                Log.e("userId", userId + "");
                if (userId != null) {
                    SharedPreferences abc = PreferenceManager.getDefaultSharedPreferences(MainActivity.this);
                    SharedPreferences.Editor editor2 = abc.edit();
                    editor2.putString("userId", userId);
                    editor2.apply();

                } else {
                }
                Intent i = new Intent(MainActivity.this, LiveTrack.class);
                i.putExtra("userId", userId);
                startActivity(i);

            } else {
                Log.e("response", "onloginfailed");
                validate();
                Toast.makeText(MainActivity.this, "Smth went wrong. Please check your network and try again", Toast.LENGTH_SHORT).show();
            }
        } catch (JSONException e) {
            Log.e("Json", "execption" + e);
        }
    }
}

private String getPostDataString(HashMap<String, String> params) throws UnsupportedEncodingException {
    StringBuilder result = new StringBuilder();
    boolean first = true;
    for (Map.Entry<String, String> entry : params.entrySet()) {
        if (first)
            first = false;
        else
            result.append("&");

        result.append(URLEncoder.encode(entry.getKey(), "UTF-8"));
        result.append("=");
        result.append(URLEncoder.encode(entry.getValue(), "UTF-8"));
    }

    return result.toString();
}
Abdul Waheed
  • 4,540
  • 6
  • 35
  • 58
Amrita Stha
  • 2,973
  • 3
  • 25
  • 46

3 Answers3

0

So your question is why it's crashing even though you have set the Try/Catch. So my answer is you have catch the JSONException exception and that is for Json-Parsing related.

So use Try/Catch as below.

JSONObject jsonResponse = null;
    try {
        jsonResponse = new JSONObject(response.toString());
        status = jsonResponse.getString("status");
        responseMsg = jsonResponse.getString("message");

        if (status.equalsIgnoreCase("true")) {
            Log.e("response ", response + "");

            JSONObject jsonResponse1 = jsonResponse.getJSONObject("data");
            String userId = jsonResponse1.getString("user_id");
            Log.e("userId", userId + "");
            if (userId != null) {
                SharedPreferences abc = PreferenceManager.getDefaultSharedPreferences(MainActivity.this);
                SharedPreferences.Editor editor2 = abc.edit();
                editor2.putString("userId", userId);
                editor2.apply();

            } else {
            }
            Intent i = new Intent(MainActivity.this, LiveTrack.class);
            i.putExtra("userId", userId);
            startActivity(i);

        } else {
            Log.e("response", "onloginfailed");
            validate();
            Toast.makeText(MainActivity.this, "Smth went wrong. Please check your network and try again", Toast.LENGTH_SHORT).show();
        }
    } catch (JSONException e) {
        Log.e("Json", "execption" + e);
    } catch (Exception e) {
        Log.e("Generic", "execption" + e);
    }

Please note in above I have added one more Catch with generic Exception. Hope this works for you.

android_griezmann
  • 3,757
  • 4
  • 16
  • 43
  • This is not the issue, the error explicitly complains about `toString()` being run on a null object. Catching generic exceptions doesn't solve the problem. – Qrchack Nov 06 '17 at 11:23
0

The actual problem is somewhere else. Your onPostExecute(String result) executes the following:

jsonResponse = new JSONObject(response.toString());

However, at the end of your doInBackground() you have explicitly said:

return null; 

doInBackground() is supposed to return a Result (see documentation). You're returning null, so in your onPostExecute() you always do this if the connection fails:

jsonResponse = new JSONObject(null.toString());

Hence, your app crashes and Android runtime complains about you trying to run toString() on null. To fix the issue, you have to return the String result you want in doInBackground()

Qrchack
  • 899
  • 1
  • 10
  • 20
  • That said, you should check if `response == null` in `onPostExecute()` before calling `toString()` on it anyway. You should also not return `null` as a response. Just return a empty String (`""`) and in `onPostExecute()` check if the response isn't empty. – Qrchack Nov 06 '17 at 11:44
0

on onPostExecute() before jsonResponse = new JSONObject(response.toString()); enter this: if(response == null)return;

Royz
  • 145
  • 1
  • 15
  • 1
    You should probably handle the situation and at least add a message that the connection failed before returning – Qrchack Nov 06 '17 at 15:48