Ошибка залпа NullPointerException на String.length () - PullRequest
0 голосов
/ 19 сентября 2018

Мне не удалось найти какое-либо существующее решение моей загадочной проблемы.Вот оно: у меня есть запрос залпа, который заполняет некоторые поля в моем фрагменте.Иногда, и здесь возникает проблема (это происходит не всегда), он генерирует исключение NullPointerException из-за метода «String.length ()».Я не могу найти, где ошибка.

Вот ошибка:

com.android.volley.VolleyError: java.lang.NullPointerException: попытка вызвать виртуальный метод "int java.lang.String.length () "для ссылки на пустой объект.

Вот мой запрос залпа:

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

Вот 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

Имейте в виду, что если я вернусь к своей основной деятельности, а затем снова открою фрагмент, все работает нормально.Я думал, что это может быть проблема с задержкой сервера, но как ее решить?

Спасибо всем.Итак, позвольте мне обновить:

Об ответе

это мой php код

<?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);
?>

это мой ответ

[{"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}]

на стороне сервера, все работает как положено.

Об отладке

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

Установка точки отладки в преобразовании JSON, я заметил, что отладка победила 'не запускается, если выброшено исключение.Очевидно, это не помогает.

Кроме того, я пытался добавить это выражение if, как только запускается метод onResponse, но тоже не помогло.

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

это строка, импортируемая через SharedPreferences, все хорошо, это просто адрес электронной почты, он всегда заполнен.

Запрос залпа

Запросыотправляются по шаблону синглтона

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

в методе запроса: SingletonVolley.getInstance(getActivity().getApplicationContext()).addToRequestQueue(stringRequest);

, и это php url

приватная статическая строка FORMBODY_PHP = "http://towmyride.000webhostapp.com/php/form_body.php";

Я думаю, это не касается самого кода, такого как переменные, но это как-то связано с контекстом. Я вызываю этот метод во фрагменте метода onViewCreated, верно?

Ответы [ 3 ]

0 голосов
/ 19 сентября 2018

Проблема в ответе JSON

Ваш ответ JSON пуст.И я думаю, что проблема может заключаться в этих двух строках.

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

Ваше значение rawPunti равно нулю, и поэтому при разборе целочисленного значения получается исключение NullPointerException.

Итак, для отладки вам следуетдобавьте logcat для вашего ответа JSON.Затем подготовьте JsonResponse должным образом.Я думаю, что ваш код в порядке, если ваш ответ является действительным JSON.

Только для вашего последнего утверждения

Вы, наконец, упомянули, что используете фрагмент.Но нет кода.Поэтому убедитесь, что ваш фрагмент инициализируется после инициализации данных сервера во фрагмент.В этом случае вы можете получить NullPointerException в первый раз.Но это исключение не имеет к этому отношения.

0 голосов
/ 19 сентября 2018

решено

В конце концов, я нашел решение.Проблема была в моем параметре KEY_EMAIL в методе Volley getParams (), как рекомендовал кто-то из вас, ребята.Иногда обработка фрагментов может быть немного сложнее.Параметр KEY_EMAIL был импортирован Bundle из другого фрагмента, и я импортировал его в метод onStart () во фрагменте назначения.Поэтому я переместил импорт из onStart () прямо в метод getParams (), и теперь все в порядке.

Подводя итог:

  1. Ошибка залпа - исключение нулевого указателябросается на Response, когда он нулевой.

  2. Причина номер 1 Ответ может быть нулевым из-за того, что параметры в getParams () равны нулю.В моем случае я смог решить проблему, используя:

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

даже если я не смог разобраться с отладкой.

Надежда может кому-то помочь.Спасибо, ребята.

0 голосов
/ 19 сентября 2018

Вы должны добавить проверку перед получением строкового значения и перед преобразованием в int, как это

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