Android静态模型始终返回null

时间:2015-10-16 16:41:32

标签: android

我目前正在使用AsynchttpClient向Web服务器发出POST请求。当我调试时,我可以清楚地看到正在返回的JSON。但是,当我将变量设置为ECUser类中的静态方法时,我总是得到ECUser.getCurrentUser()为null,这应该是正确的。由于ECUser中的所有方法都是静态的,我不知道我的问题是什么。

如果我尝试从asynchttpclient调用中将jsonobject分配给responseBody,则会发生同样的事情。匿名类终止后,jsonobject由于某种原因始终为null。

private void attemptLogin(){
        RequestParams params = new RequestParams();
        params.put("email", userEmail.getText().toString());
        params.put("password", userPass.getText().toString());
        ECApiManager.post(Constants.loginAPI, params, new JsonHttpResponseHandler() {
            @Override
            public void onSuccess(int statusCode, Header[] headers, JSONObject responseBody) {
                //called when response code 200
                try{
                    ECUser.setCurrentUser(new ECUser(responseBody));
                    Log.d("login", responseBody.toString());
                }catch(JSONException e){
                    e.printStackTrace();
                }

            }

        });

        if (ECUser.getCurrentUser() == null) {
            ((OnLoginListener) getActivity()).loginSuccessful(false);
        }

这是我的ECUser级别。

public class ECUser {


    private static ECUser currentUser;
    private static String userToken;
    private String firstName;
    private String lastName;
    private static String userID;
    private JSONObject jObject;
    private boolean loginSuccess;


    public ECUser(JSONObject data) throws JSONException {
        this.jObject = data;
        try {
            this.loginSuccess = Boolean.parseBoolean(this.jObject.getString("success"));
            if (this.loginSuccess) {
                this.userToken = this.jObject.getString("token");
                this.firstName = this.jObject.getJSONObject("user").getString("firstname");
                this.lastName = this.jObject.getJSONObject("user").getString("lastname");
                this.userID = this.jObject.getJSONObject("user").getString("id");
            }


        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

    /**
     * Method that refreshes the state of the current user by calling the API again.
     */
    public static void refreshCurrentUser() {
        RequestParams params = new RequestParams();
        params.put("token", userToken);
        //Gotta put in user ID too.
        params.put("user_id", userID);
        // TODO: This should only call https://edu.chat/api/user, @JACOB
        ECApiManager.get(Constants.refreshUserAPI, params, new JsonHttpResponseHandler() {
            @Override
            public void onSuccess(int statusCode, Header[] headers, JSONObject responseBody) {

                try {
                    ECUser.setCurrentUser(new ECUser(responseBody));

                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }

        });
    }

    // Static

    public static ECUser getCurrentUser() {
        return ECUser.currentUser;
    }

    public static void setCurrentUser(ECUser user) {ECUser.currentUser = user;}

    public static String getUserToken() {
        return ECUser.userToken;
    }

    // Dynamic

    public String getLastName() {
        return this.lastName;
    }

    public String getFirstName() {
        return this.firstName;
    }

    public boolean getLoginSuccessful() {
        return this.loginSuccess;
    }


}

1 个答案:

答案 0 :(得分:1)

您将ECApiManager#post中的登录尝试视为同步方法,例如一旦尝试完成就返回一个。因此,在调用post之后,您将检查当前用户。

但是,从http客户端的名称(AsynchttpClient)可以清楚地看出,帖子是异步调用,这意味着HTTP请求将在后台执行,一旦成功完成,它就会将调用您的JsonHttpResponseHandler#onSuccess方法。这意味着虽然ECApiManager#post将立即返回,但当前用户尚未设置。

在异步模式下编程时,您需要处理发生的事件,而不是按顺序调用所有事件。如果您确实想要使其同步,则需要使用同步http客户端(例如HttpClient或HttpUrlConnection),或者添加Semaphore以等待HTTP请求完成。

例如:

private void attemptLogin(){
    Semaphore sema = Semaphore(1);
    sema.acquire();
    // ....
    ECApiManager.post(Constants.loginAPI, params, new JsonHttpResponseHandler() {
        @Override
        public void onSuccess(int statusCode, Header[] headers, JSONObject responseBody) {
            //called when response code 200
            try{
                ECUser.setCurrentUser(new ECUser(responseBody));
                Log.d("login", responseBody.toString());
            }catch(JSONException e){
                e.printStackTrace();
            }
            finally {
                sema.release();
            }
        }

    });
    sema.acquire();
    if (ECUser.getCurrentUser() == null) {
        ((OnLoginListener) getActivity()).loginSuccessful(false);
    }

请注意,如果您使用信号量,则还需要在失败时释放它。