Android 布尔标志始终为false
我试图与API交互,并通过比较当前电子邮件(存储在SharedPrefs中)和API返回的电子邮件来检查JSON响应,从而查看用户是否存在于该API上。如果用户存在,则设置一个标志true,这样应用程序就不会发送POST请求来保存新用户,如果该标志为false,则用户将保存在API中 因此,这是UEC(UserExistenceChecker)类Android 布尔标志始终为false,android,retrofit2,android-sharedpreferences,Android,Retrofit2,Android Sharedpreferences,我试图与API交互,并通过比较当前电子邮件(存储在SharedPrefs中)和API返回的电子邮件来检查JSON响应,从而查看用户是否存在于该API上。如果用户存在,则设置一个标志true,这样应用程序就不会发送POST请求来保存新用户,如果该标志为false,则用户将保存在API中 因此,这是UEC(UserExistenceChecker)类 public class UEC extends AppCompatActivity { List<SavePlace> userInf
public class UEC extends AppCompatActivity {
List<SavePlace> userInfo;
String name;
boolean flag;
SharedPreferences sharedPref;
public UEC(SharedPreferences sharedPref){
this.sharedPref = sharedPref;
}
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
public boolean checkIfUserExists() {
email = sharedPref.getString("userEmail", "");
Retrofit retrofitCheckUser = ApiClientSavePlace.getClient();
ApiInterfaceSavePlace apiInterfaceSavePlace = retrofitCheckUser.create(ApiInterfaceSavePlace.class);
final Call<List<SavePlace>> checkUser = apiInterfaceSavePlace.getSavePlaces();
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));
flag = true;
SharedPreferences.Editor editor = sharedPref.edit();
editor.putInt("userID", userInfo.get(i).getId());
Log.d("ID returned", String.valueOf(userInfo.get(i).getId()));
editor.apply();
break;
}
}
}
} 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;
}
}
现在的问题是,根据日志,else条件始终为true,因为标志始终为false,即使我在checkIfUserExists()方法中将其设置为true
日志的有趣之处在于
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
首先出现,然后在上面的日志之后的日志中出现
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
这意味着它检测到了电子邮件并设置了sharedpref
但这面旗帜仍然是假的 该行为是由于异步执行了
checkUser.enqueue(new Callback()
。因此,当您从checkIfUserExists()
调用此方法时,您的执行线程将不会等待checkUser.enqueue()
完成。相反,它将立即转到下一行并返回当前标志值,该值为false。checkUser.enqueue()
将在后台线程中执行,您将在onResponse()中获得结果
method。根据您的代码,该行为是正确的。请尝试异步处理场景,因为这是网络调用的推荐方法。快速查看您的代码,似乎enqueue方法导致布尔值仅在调用checkIfUserExists()后才更改为true
方法
这是您在日志中看到的,由于排队方法的异步性质,您的onResponse()
和onFailure()
中的所有代码仅在后台线程中的所有其他代码之后执行
为了避免这种情况,您可以实现回调方法,以便在完成onResponse()
方法时调用该方法以检查用户是否存在。在下面的代码中,回调方法是onUserExists()
替换了true boolean标志,我还包括了一个else语句,如果用户不存在,它将触发第二次回调,onUserDoesNotExist()
方法。这些回调方法将触发onUserExists()
和onUserDoesNotExist()中main活动中的代码
方法
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;
}
最后,这就是您的主要活动现在的样子
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)));
}
);
}
我不确定这段代码是否能成功编译和运行,因为我自己还没有运行过这段代码。希望它能解决您的问题。问题是,调用此方法时,您正在处理异步函数调用
uec.checkIfUserExists();
此函数中的代码以正常方式执行,直到在此处进行api调用的那一行
final Call<List<SavePlace>> checkUser = apiInterfaceSavePlace.getSavePlaces();
方法执行,这是一个回调方法,您可以使用true标志获取值
解决方案
您应该等待api调用完成,然后对用户是否存在执行任何检查。
因此,一种简单的方法是将用户存在检查放在onResponse()回调方法本身中
如果您想在活动或片段中处理它,您可以创建自己的回调方法并将其传递给checkIfUserExists();
像这样的
public interface MyInterface{
public void onCallback(boolean isUserExists);
}
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
}
});
}
在你的活动中
uec.checkIfUserExists(
new MyInterface(){
@Override
public void onCallback(boolean isUserExists){
if (isUserExists) {
//your code
}
else{
//your code
}
}
}
);
对checkIfUserExists()方法进行如下更改
public interface MyInterface{
public void onCallback(boolean isUserExists);
}
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
}
});
}
public void checkIfUserExists(最终MyInterface MyInterface){
//你的代码
checkUser.enqueue(新回调(最终MyInterface MyInterface){
@凌驾
公共void onResponse(调用、响应){
userInfo=response.body();
试一试{
//你的代码
if(emailReturned.equals(email)){
flag=true;
}
//在此处将您的标志传递给回调方法。
myInterface.onCallback(标志);
}
}捕获(例外e){
e、 printStackTrace();
}
}
@凌驾
失败时公共无效(调用、可丢弃){
//处理失败
}
});
}
是的,我现在明白了。谢谢。你能想到这个问题的可能解决方案吗?你好。谢谢你的回答。我在实现你的解决方案时遇到了困难。请参见此屏幕截图:@mnmncp firstonUserExistsCallback
应该是大写字母“O”而不是小写字母“O”。你的接口名称也有小写字母“O”o'在beginning@mnmncppublic void checkIfUserExists(OnUserExistsCallback OnUserExistsCallback)
您没有包含参数needed抱歉,这是我的错误。因此,我已经实现了解决方案,但在日志中得到了这一点:感谢您的响应。您能告诉我如何使用接口调用checkIfUserExists()或enqueue方法中的onCallBack方法吗?
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
}
});
}