布尔标志始终为false

时间:2017-05-13 19:12:16

标签: android retrofit2 android-sharedpreferences

我正在尝试与API进行交互,并通过将当前电子邮件(存储在SharedPrefs中)与从API返回的电子邮件进行比较来检查JSON响应,以查看用户是否存在该API。如果用户存在,则标记设置为 true ,以便应用程序不发送POST请求以保存新用户,如果 false ,则用户将被保存在API中。

所以,这是 UEC(UserExistenceChecker)类

public class MainActivity{

SharedPreferences sharedPref = 
PreferenceManager.getDefaultSharedPreferences(getBaseContext());

    UEC uec = new UEC(sharedPref);
    boolean userExists = uec.checkIfUserExists();
    if (userExists) {
        Log.d("USERSTATUS", String.valueOf(sharedPref.getInt("userID", 0)));
    } else {
        Log.d("USERSTATUS", "FALSE:DOESNT EXIST");
        Log.d("USERSTATUS", String.valueOf(sharedPref.getInt("userID", 0)));
    }
}

在本课程中,我制作了一个布尔标志,其默认值为 false

这就是我从 MainActivity.java

中调用方法 checkIfUserExists()的方法
05-13 15:27:54.278 1613-1613/xyz.gautamhans.locus D/USERSTATUS: FALSE:DOESNT 
EXIST
05-13 15:27:54.278 1613-1613/xyz.gautamhans.locus D/USERSTATUS: 12

现在,问题在于,根据日志,其他条件始终为 true ,因为标记始终为 false 即使我在 checkIfUserExists()方法中将其设置为 true

日志有趣的是这个

05-13 15:27:55.746 1613-1613/xyz.gautamhans.locus D/response: email 
returned: some-email@gmail.com
05-13 15:27:55.749 1613-1613/xyz.gautamhans.locus D/sharedpref: email: 
some-email@gmail.com
05-13 15:27:55.749 1613-1613/xyz.gautamhans.locus D/response: email 
returned: some-email@gmail.com
05-13 15:27:55.749 1613-1613/xyz.gautamhans.locus D/sharedpref: email: 
some-email@gmail.com
05-13 15:27:55.749 1613-1613/xyz.gautamhans.locus D/response: email match?: 
true
05-13 15:27:55.749 1613-1613/xyz.gautamhans.locus D/ID returned: 12

首先出现,然后在日志

之后出现在日志中
{{1}}

表示它检测到电子邮件并设置了sharedpref 但国旗仍然是假的。

3 个答案:

答案 0 :(得分:1)

通过快速查看代码,看起来enqueue方法导致在调用checkIfUserExists()方法后布尔值只能更改为true。

这是您在日志中看到的内容,由于enqueue方法的异步特性,onResponse()onFailure()中的所有代码仅在后台线程中的所有其他代码之后执行

为了避免这种情况,您可以实现一个回调方法,以便每当onResponse()方法完成时,您都可以调用该方法来检查用户是否存在。在下面的代码中,回调方法是onUserExists(),它替换了真正的布尔标志,如果用户不存在,我还会包含一个else语句,这将触发第二个回调,即onUserDoesNotExist()方法。这些回调方法将在那里的onUserExists()onUserDoesNotExist()方法中触发MainActivity中的代码。

public void checkIfUserExists(OnUserExistsCallback onUserExistsCallback) {

    email = sharedPref.getString("userEmail", "");

    Retrofit retrofitCheckUser = ApiClientSavePlace.getClient();
    ApiInterfaceSavePlace apiInterfaceSavePlace = retrofitCheckUser.create(ApiInterfaceSavePlace.class);
    final Call<List<SavePlace>> checkUser = apiInterfaceSavePlace.getSavePlaces();
    OnUserExistsCallback callback = onUserExistsCallback;
    checkUser.enqueue(new Callback<List<SavePlace>>() {
        @Override
        public void onResponse(Call<List<SavePlace>> call, Response<List<SavePlace>> response) {
            userInfo = response.body();
            try {
                if(userInfo.size()!=0){
                    for (int i = 0; i <= userInfo.size(); i++) {
                        String emailReturned = userInfo.get(i).getEmail();
                        Log.d("response", "email returned: " + emailReturned);
                        Log.d("sharedpref", "email: " + email);
                        if (emailReturned.equals(email)) {
                        Log.d("response:", "email match?: " + emailReturned.equals(email));
                            SharedPreferences.Editor editor = sharedPref.edit();
                            editor.putInt("userID", userInfo.get(i).getId());
                            Log.d("ID returned", String.valueOf(userInfo.get(i).getId()));
                            editor.apply();
                            callback.onUserExists();
                            break;
                        } else {
                            callback.onUserDoesNotExist();
                        }
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onFailure(Call<List<SavePlace>> call, Throwable throwable) {
            Log.d("RESPONSE", "FAILED CHECKING USER ID/SOMETHING HAPPENED");
        }
    });
    return flag;
}

为此,您需要创建OnUserExistsCallback接口。

public interface OnUserExistsCallback {
     void onUserExists();

     void onUserDoesNotExist();
}

最后,这就是您的MainActivity现在的样子。

public class MainActivity {

    SharedPreferences sharedPref =
        PreferenceManager.getDefaultSharedPreferences(getBaseContext());

    UEC uec = new UEC(sharedPref);
    uec.checkIfUserExists(new OnUserExistsCallback() {
            @Override
            public void onUserExists() {
                Log.d("USERSTATUS", String.valueOf(sharedPref.getInt("userID", 0)));
            }

            @Override
            public void onUserDoesNotExist() {
                Log.d("USERSTATUS", "FALSE:DOESNT EXIST");
                Log.d("USERSTATUS", String.valueOf(sharedPref.getInt("userID", 0)));
            }

        );
    }

不确定这是否会编译并成功运行,因为我自己没有运行此代码。希望它会解决你的问题。

答案 1 :(得分:0)

该行为是由checkUser.enqueue(new Callback<List<SavePlace>>()的异步执行引起的。因此,当您从checkIfUserExists()调用此方法时,您的执行线程将不会等待checkUser.enqueue()完成。相反,它将立即转到下一行并返回当前标志值false。 checkUser.enqueue()将在后台线程中执行,您将以onResponse()方法获得结果。根据您的代码,行为是正确的。请尝试异步处理场景,因为这是网络呼叫的推荐方法。

答案 2 :(得分:0)

问题是你在调用这个方法时正在处理异步函数调用

uec.checkIfUserExists();

此函数中的代码以正常方式执行,直到您在此处调用api的行

final Call<List<SavePlace>> checkUser = apiInterfaceSavePlace.getSavePlaces();

在后台线程中进行web api调用,并且您的函数以正常方式执行并返回,这意味着您将获得标记为false值。 当后台任务完成后,然后是

中的代码
public void onResponse() 
执行

方法,这是一种回调方法,您可以使用true flag获取值。

<强>解决方案

您应该等待api调用完成,然后对用户是否存在执行任何检查。 因此,一种简单的方法是将用户存在的内部检查onResponse()回调方法本身。

如果你想在你的活动或片段中处理它,你可以创建自己的回调方法并将其传递给checkIfUserExists();

像这样的东西

public interface MyInterface{
    public void onCallback(boolean isUserExists);
}

并在您的活动中

uec.checkIfUserExists(
    new MyInterface(){
        @Override
        public void onCallback(boolean isUserExists){
            if (isUserExists) {
                //your code
            }
            else{
                //your code
            }
        }
    }
);

像你这样更改checkIfUserExists()方法

public void checkIfUserExists(final MyInterface myInterface) {
    //your code
    checkUser.enqueue(new Callback<List<SavePlace>>(final MyInterface myInterface) {
        @Override
        public void onResponse(Call<List<SavePlace>> call, Response<List<SavePlace>> response) {
            userInfo = response.body();
            try {
               //your code
                    if (emailReturned.equals(email)) {
                        flag = true;
                    }
                    //pass your flag to callback method here.
                    myInterface.onCallback(flag);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onFailure(Call<List<SavePlace>> call, Throwable throwable) {
          //Handle failure
        }
    });
}