【问题标题】:Java - NullPointerException when getting JSONObjectJava - 获取 JSONObject 时出现 NullPointerException
【发布时间】:2013-01-06 08:49:55
【问题描述】:

我正在尝试使用Lukencode 的 RestClient 类在我的 Android 应用中实现登录功能。我有一个名为 UserFunctions 的类来通过 RestClient 检索 JSONObject:

public class UserFunctions {

    private RestClient restClient;
    private String json;
    private Context mContext;

    private static String login_tag = "login";
    private static String register_tag = "register";

    // constructor
    public UserFunctions(Context context){
        restClient = new RestClient("http://10.0.2.2:81/HGourmet/user");
        mContext = context;
    }

    /**
     * function make Login Request
     * @param email
     * @param password
     * */
   public JSONObject loginUser(String email, String password){
        // Building Parameters      
        restClient.AddParam("tag", login_tag);
        restClient.AddParam("email", email);
        restClient.AddParam("password", password);

        // getting JSON Object
        try{
    restClient.Execute(RequestMethod.POST);
    }catch(Exception e){
        e.printStackTrace();
    }               
    json = restClient.getResponse();

        JSONObject jObj = null;
        try {
            jObj = new JSONObject(json);
        } catch (JSONException e) {
            Log.e("JSON Parser", "Error parsing data " + e.toString());
        }
        return jObj;
    }

以下是我在 logcat 中得到的:

01-06 09:01:05.805: E/Trace(1819): error opening trace file: No such file or directory (2)
01-06 09:02:05.485: E/AndroidRuntime(1819): FATAL EXCEPTION: main
01-06 09:02:05.485: E/AndroidRuntime(1819): java.lang.NullPointerException
01-06 09:02:05.485: E/AndroidRuntime(1819):     at org.json.JSONTokener.nextCleanInternal(JSONTokener.java:116)
01-06 09:02:05.485: E/AndroidRuntime(1819):     at org.json.JSONTokener.nextValue(JSONTokener.java:94)
01-06 09:02:05.485: E/AndroidRuntime(1819):     at org.json.JSONObject.<init>(JSONObject.java:154)
01-06 09:02:05.485: E/AndroidRuntime(1819):     at org.json.JSONObject.<init>(JSONObject.java:171)
01-06 09:02:05.485: E/AndroidRuntime(1819):     at com.hanu.hgourmet.library.UserFunctions.loginUser(UserFunctions.java:49)
01-06 09:02:05.485: E/AndroidRuntime(1819):     at com.hanu.hgourmet.LoginActivity$1.onClick(LoginActivity.java:56)
01-06 09:02:05.485: E/AndroidRuntime(1819):     at android.view.View.performClick(View.java:4202)
01-06 09:02:05.485: E/AndroidRuntime(1819):     at android.view.View$PerformClick.run(View.java:17340)
01-06 09:02:05.485: E/AndroidRuntime(1819):     at android.os.Handler.handleCallback(Handler.java:725)
01-06 09:02:05.485: E/AndroidRuntime(1819):     at android.os.Handler.dispatchMessage(Handler.java:92)
01-06 09:02:05.485: E/AndroidRuntime(1819):     at android.os.Looper.loop(Looper.java:137)
01-06 09:02:05.485: E/AndroidRuntime(1819):     at android.app.ActivityThread.main(ActivityThread.java:5039)
01-06 09:02:05.485: E/AndroidRuntime(1819):     at java.lang.reflect.Method.invokeNative(Native Method)
01-06 09:02:05.485: E/AndroidRuntime(1819):     at java.lang.reflect.Method.invoke(Method.java:511)
01-06 09:02:05.485: E/AndroidRuntime(1819):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
01-06 09:02:05.485: E/AndroidRuntime(1819):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
01-06 09:02:05.485: E/AndroidRuntime(1819):     at dalvik.system.NativeStart.main(Native Method)

我真的希望有人能帮我找出这个问题的原因。非常感谢。

【问题讨论】:

  • public JSONObject loginUser(String email, String password) 返回jObj,但不创建jObj。也许这是你的问题?
  • jObj 在我调用 new GetUser().execute(); 时已经创建,不是吗?
  • 这太令人沮丧了。难道你没有意识到 logcat 堆栈跟踪会准确地告诉你错误在哪一行? Toast 不是调试的好方法。使用调试器单步执行您的代码。同时,请发布异常的堆栈跟踪。
  • No jObj 不会被初始化,因为GetUser 是一个AsyncTask,它在不同的线程中运行,并且在调用new GetUser().execute(); 之后,控件不会等待AsyncTask 完成并且控件向前移动并且返回未初始化的jObj
  • @strawberryjam 发布堆栈跟踪... errr... 西蒙说发布堆栈跟踪。如果没有堆栈跟踪的可能性,您只会收到有关丢失堆栈跟踪的投诉,或者是对问题的猜测。

标签: java android json rest nullpointerexception


【解决方案1】:

我不会详细说明您应该如何执行此操作,而只会详细说明它发生的原因。根据定义,AsyncTask 是异步的。这意味着当您执行它时,它会在不同的线程中并行执行其工作。所以你不能指望它在execute() 被调用后立即终止(否则它会被称为SyncTask,并且没有任何存在的理由)。

请参阅AsyncTask 作为烤面包机。当您启动烤面包机(执行 AsyncTask)时,它会烤面包,但不会立即返回烤面包。烤它需要一些时间。当它烤面包时,您可以做其他事情(因此不会完全冻结 UI 线程)。当它烤完你的面包时,它会用 ding! 通知你面包烤好了。这里也是一样。只有在 AsyncTask 通知您它已完成执行时,您才应该开始使用 json(烤面包)。

【讨论】:

  • 非常感谢您对我的启发。我会看看我能做些什么来解决这个问题。
  • 喜欢烤面包机的比喻。 +1
  • 为了扩展这一点,在我看来 getResponse()null。它被传递给JSONTokener,它试图在没有空检查的情况下访问输入的长度。似乎这实际上是JSONTokener 中的一个错误。
  • @TomLubitz 因为即使没有 Asynctask 我也面临这个问题,我也这么认为。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-29
  • 2021-12-13
  • 1970-01-01
  • 2012-06-19
相关资源
最近更新 更多