-1

I was not able to find some existing solution to my enigmatic issue. Here it is: I've got a volley request that populates some fields in my fragment. Sometimes, and here is the problem (it does not occur always), it throws a NullPointerException due to "String.length()" method. I can't find where the bug is.

Here is the error:

com.android.volley.VolleyError: java.lang.NullPointerException: Attempt to invoke virtual method "int java.lang.String.length()" on a null object reference.

Here is my volley request:

private void loadFormBody() {
    StringRequest stringRequest = new StringRequest(Request.Method.POST, FORMBODY_PHP, new Response.Listener<String>() {
        @Override
        public void onResponse(String response) {
            try {
                JSONArray jsonFormBody = new JSONArray(response);
                for (int i = 0; i < jsonFormBody.length(); i++) {
                    JSONObject jsonObject1 = jsonFormBody.getJSONObject(i);
                    String mezzo = jsonObject1.getString("mezzo");
                    String casa_lavoro = jsonObject1.getString("casa_lavoro");
                    String lavoro_casa = jsonObject1.getString("lavoro_casa");
                    String rawData = jsonObject1.getString("timestamp");
                    String rawPunti = jsonObject1.getString("punti_passaggio");
                    int punti = Integer.parseInt(rawPunti);
                    if (casa_lavoro.equals("1") && lavoro_casa.equals("0")) {
                        tipoPassaggio = "Casa > Lavoro";
                    } else if (lavoro_casa.equals("1") && casa_lavoro.equals("0")) {
                        tipoPassaggio = "Lavoro > Casa";
                    }
                    try {
                        String[] date = rawData.split("-|:| ");
                        yearPassaggio = date[0];
                        monthPassaggio = date[1];
                        dayPassaggio = date[2];
                        hourPassaggio = date[3];
                        minutePassaggio = date[4];
                        secondPassaggio = date[5];
                        dataPassaggio = dayPassaggio + "/" + monthPassaggio + "/" + yearPassaggio;
                    } catch (ArrayIndexOutOfBoundsException e) {
                        e.printStackTrace();
                    }
                    listTable.add(new ObjUserTable(mezzo, tipoPassaggio, dataPassaggio, punti));
                }
                adapterUserTable = new AdapterUserTable(getContext(), listTable);
                lvUserTable.setAdapter(adapterUserTable);
            } catch (JSONException e) {
                Toast.makeText(getContext(), "Decodifica JSON Fallita: " + e.toString(), Toast.LENGTH_SHORT).show();
            }
        }
    }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            Toast.makeText(getContext(), "Popolamento FallitoB: " + error.toString(), Toast.LENGTH_LONG).show();
        }
    }) {
        @Override
        protected Map<String, String> getParams() throws AuthFailureError {
            Map<String, String> params = new HashMap<String, String>();
            params.put("email", KEY_EMAIL);
            return params;
        }
    };
    SingletonVolley.getInstance(getActivity().getApplicationContext()).addToRequestQueue(stringRequest);
}

Here is logcat:

09-19 08:49:23.242 21225-21253/? E/Volley: [523] NetworkDispatcher.processRequest: Unhandled exception java.lang.NullPointerException: Attempt to invoke virtual method 'int java.lang.String.length()' on a null object reference
java.lang.NullPointerException: Attempt to invoke virtual method 'int java.lang.String.length()' on a null object reference
    at java.net.URLEncoder.encode(URLEncoder.java:204)
    at com.android.volley.Request.encodeParameters(Request.java:491)
    at com.android.volley.Request.getBody(Request.java:477)
    at com.android.volley.toolbox.HurlStack.addBodyIfExists(HurlStack.java:245)
    at com.android.volley.toolbox.HurlStack.setConnectionParametersForRequest(HurlStack.java:219)
    at com.android.volley.toolbox.HurlStack.executeRequest(HurlStack.java:97)
    at com.android.volley.toolbox.BasicNetwork.performRequest(BasicNetwork.java:131)
    at com.android.volley.NetworkDispatcher.processRequest(NetworkDispatcher.java:120)
    at com.android.volley.NetworkDispatcher.run(NetworkDispatcher.java:87)
09-19 08:49:23.298 1882-1896/system_process E/memtrack: Couldn't load memtrack module

Bare in mind that if I go back to my main activity and then re-open the fragment, everything works fine. I thought it may be a server-delay issue, but how to sort it out?

Thank you everyone. So let me update:

About Response

this is my php code

<?php
require('connection.php');
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
    $email = $_POST['email'];
    $sql = "SELECT mezzo, timestamp, casa_lavoro, lavoro_casa, punti_passaggio FROM passaggi WHERE email_userdata='$email'";
    if ($stmt = mysqli_prepare($conn, $sql)) {
        mysqli_stmt_execute($stmt);
        $userstable = mysqli_stmt_get_result($stmt);
        $json = mysqli_fetch_all($userstable, MYSQLI_ASSOC);
        echo json_encode($json);
    }
    mysqli_stmt_free_result($stmt);
    mysqli_stmt_close($stmt);
} else {
    echo "Error";
}
mysqli_close($conn);
?>

this is my response

[{"mezzo":"Skate","timestamp":"2018-07-15 16:37:00","casa_lavoro":1,"lavoro_casa":0,"punti_passaggio":55},{"mezzo":"Bici","timestamp":"2018-07-20 10:14:03","casa_lavoro":0,"lavoro_casa":1,"punti_passaggio":50},{"mezzo":"Skate","timestamp":"2018-07-25 17:30:00","casa_lavoro":0,"lavoro_casa":1,"punti_passaggio":60},{"mezzo":"Carpooling","timestamp":"2018-09-12 22:38:34","casa_lavoro":1,"lavoro_casa":0,"punti_passaggio":20},{"mezzo":"A Piedi","timestamp":"2018-09-17 10:24:17","casa_lavoro":1,"lavoro_casa":0,"punti_passaggio":90},{"mezzo":"A Piedi","timestamp":"2018-09-17 10:24:36","casa_lavoro":0,"lavoro_casa":1,"punti_passaggio":90}]

Server-Side, everything works as expected.

About Debug

    try {
DP      JSONArray jsonFormHeader = new JSONArray(response);
        for (int i = 0; i < jsonFormHeader.length(); i++) { ...

Setting debug point in the JSON conversion, I've noticed that debug won't start if the exception is thrown. Obviously this is not helping.

Also, I've tried to add this if statement as soon as onResponse method starts, but did not help too.

public void onResponse(String response) {
    if (response != null && response.length() > 0) {
        try {
            JSONArray jsonFormHeader = new JSONArray(response);
            for (int i = 0; i < jsonFormHeader.length(); i++) { ...

KEY_EMAIL

this is a String imported via SharedPreferences, it's fine, it's just an email address, it's always populated.

Volley Request

Requests are sent by singleton pattern

import android.content.Context;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.toolbox.Volley;

public class SingletonVolley {

    private static SingletonVolley mInstance;
    private static Context mCtx;
    private RequestQueue requestQueue;

    private SingletonVolley(Context context) {
        mCtx = context;
        requestQueue = getRequestQueue();
    }

    public static synchronized SingletonVolley getInstance(Context context) {
        if (mInstance == null) {
            mInstance = new SingletonVolley(context);
        }
        return mInstance;
    }

    public RequestQueue getRequestQueue() {
        if (requestQueue == null) {
            requestQueue = Volley.newRequestQueue(mCtx.getApplicationContext());
        }
        return requestQueue;
    }

    public void addToRequestQueue(Request request) {
        getRequestQueue().add(request);
    }
}

in request method: SingletonVolley.getInstance(getActivity().getApplicationContext()).addToRequestQueue(stringRequest);

and this is the php url

private static String FORMBODY_PHP = "http://towmyride.000webhostapp.com/php/form_body.php";

I guess it's not concerning about code itself like variables, but it has something to do with context. I'm calling this method in a fragment onViewCreated method, is it right?

Gabry_Neo
  • 5
  • 3

3 Answers3

0

you should add check before getting string value and before conversion to int like this

 if (object.has("punti_passaggio") && !object.isNull("punti_passaggio")) {
String rawPunti = jsonObject1.getString("punti_passaggio");
} // this check is important because sometimes data from json is null or sometimes this json tag don't exist
if(rawPunti.length() != 0){
int punti = Integer.parseInt(rawPunti);
}
unzila
  • 190
  • 1
  • 12
0

Problem is in JSON Response

Your JSON response is null. And I think may be the problem is occurring in this two lines.

String rawPunti = jsonObject1.getString("punti_passaggio");
int punti = Integer.parseInt(rawPunti);

Your rawPunti value is null and that's why the Integer parsing is getting NullPointerException.

So to debug, you should add a logcat for your JSON response. Then prepare the JsonResponse properly. I think your code is okay if your response is a valid JSON.

Only for your last statement

You've mentioned at last that you are using the fragment. But there is no code. So make sure if your fragment initializes after server data initialize to the fragment. On that case, you can get the NullPointerException first time. But this exception is not related to that.

0

SOLVED

Eventually, I came up with a solution. The problem was in my KEY_EMAIL param in Volley getParams() method, as someone of you guys recommended. Sometimes handling fragments can be a bit tricky. The KEY_EMAIL param was imported by Bundle from another fragment, and I was importing it in onStart() method in destination fragment. So I moved the import from onStart() directly in my getParams() method and now everything it's fine.

To sum up:

  1. Volley Error - Null Pointer Exception is thrown on Response when it is null.

  2. Number 1 reason Response could be null is due to params in getParams() being null. In my case I was able to address the problem by using:

Log.v("PARAMS", params.toString());

even if I was not able to deal with debug.

Hope can help someone. Thank guys.

Gabry_Neo
  • 5
  • 3