Java - NullPointerException when getting JSONObjec

2019-02-26 13:58发布

问题:

I'm trying to implement a login feature in my Android app using Lukencode's RestClient class. I have a class named UserFunctions to retrieve JSONObject via RestClient:

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

And below is what I get in 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)

I really hope that someone would help me pinpoint the reason of this problem. Thank you very much.

回答1:

I won't expand on how you should do this, but only on why it happens. An AsyncTask, by definition, is asynchronous. This means that when you execute it, it does its job in parallel, in a different thread. So you can't expect it to be terminated right after execute() has been called (else it would be called SyncTask, and wouldn't have any reason to exist).

See AsyncTask as a toaster. When you start the toaster (execute the AsyncTask), it toasts your bread, but doesn't return the toasted bread immediately. It takes some time to toast it. While it's toasting your bread, you can do something else (and thus not freeze the UI thread completely). And when it has finished toasting your bread, it notifies you with a ding! that the bread is toasted. That's the same thing here. You should only start using json (the toasted bread), when the AsyncTask notifies you that it has finished executing.