首页 > 解决方案 > String.length() 上的 Volley 错误 NullPointerException

问题描述

我无法为我的神秘问题找到一些现有的解决方案。就是这样:我有一个凌空请求,它填充了我的片段中的一些字段。有时,这就是问题(它并不总是发生),由于“String.length()”方法,它会抛出 NullPointerException。我找不到错误在哪里。

这是错误:

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 转换中设置调试点,我注意到如果抛出异常,调试将不会启动。显然这没有帮助。

另外,我尝试在 onResponse 方法启动后立即添加此 if 语句,但也没有帮助。

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 网址

私有静态字符串 FORMBODY_PHP = " http://towmyride.000webhostapp.com/php/form_body.php ";

我想这与代码本身(如变量)无关,但它与上下文有关。我在片段onViewCreated方法中调用这个方法,对吗?

标签: androidlistviewnullpointerexceptionandroid-volley

解决方案


解决了

最终,我想出了一个解决方案。正如你们中的一些人所推荐的,问题出在我的 Volley getParams() 方法中的 KEY_EMAIL 参数中。有时处理片段可能有点棘手。KEY_EMAIL 参数是由 Bundle 从另一个片段导入的,我在目标片段的 onStart() 方法中导入它。所以我直接在我的 getParams() 方法中从 onStart() 移动导入,现在一切都很好。

总结一下:

  1. Volley 错误 - 当 Response 为空时,会在 Response 上引发空指针异常。

  2. 响应可能为空的第 1 个原因是由于 getParams() 中的参数为空。就我而言,我能够通过使用以下方法解决问题:

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

即使我无法处理调试。

希望可以帮助某人。谢谢大家。


推荐阅读