java - Android AsyncTask 保持返回相反的值

标签 java android android-asynctask

我在 Android Studio 中遇到 AsyncTask 问题。我想做的是在创建新用户之前,我正在检查用户名和电子邮件是否存在于我的数据库中。这是我调用创建 AsyncTask 的部分:

new SignupAsyncTask(getBaseContext()).execute(userModel);
if(SignupAsyncTask.successCheck == false){
    Toast.makeText(getBaseContext(), "Failed", Toast.LENGTH_SHORT).show();
} else if(SignupAsyncTask.successCheck == true){
    Toast.makeText(getBaseContext(), "Success", Toast.LENGTH_SHORT).show();
}

在我的 AsyncTask 中,我正在获取所有用户。然后我执行一个循环来检查是否有任何匹配的用户名或密码。如果存在,我将 successCheck 设置为 false。

public class SignupAsyncTask extends AsyncTask<User, Integer, Boolean> {
    ArrayList<User> list = new ArrayList<User>();
    DB_User userCtrl = new DB_User();
    Context context;
    public static boolean successCheck = false;

    public SignupAsyncTask(){}

    public SignupAsyncTask(Context context){
        this.context = context;
    }

    @Override
    protected Boolean doInBackground(User... params) {
        try {
            list = userCtrl.getAllUser();
            for(int i = 0; i < list.size(); i++){
                User userObj = list.get(i);
                if(params[0].getUserName().equals(userObj.getUserName())){
                    successCheck = false;
                    break;
                }
                else if (params[0].getEmail().equals(userObj.getEmail())){
                    successCheck = false;
                    break;
                } else{
                    successCheck = true;
                    break;
                }
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }

        if(successCheck == true){
            userCtrl.SignupUser(params[0]);
        }
        return successCheck;
    } 

    @Override
    protected void onPostExecute(Double result){

    }

    @Override
    protected void onProgressUpdate(Integer... progress) {

    }
}

我现在遇到的问题是,当我第一次使用不重复的用户名和电子邮件进行测试时,它可以插入数据库但不知何故 toast 打印出“失败”。

然后,当我尝试使用另一条重复记录时,它不会插入数据库,因为我将我的用户名和电子邮件设置为 UNIQUE,但 toast 打印出“成功”。

和我的代码逻辑相反的操作。有任何想法吗?

提前致谢

编辑

public class SignupAsyncTask extends AsyncTask<User, Integer, Boolean> {
ArrayList<User> list = new ArrayList<User>();
DB_User userCtrl = new DB_User();
Context lcontext;
public static boolean successCheck = false;

public SignupAsyncTask(){}

public SignupAsyncTask(Context context){
    lcontext = context;
}

@Override
protected Boolean doInBackground(User... params) {
    try {
        list = userCtrl.getAllUser();
        for(int i = 0; i < list.size(); i++){
            User userObj = list.get(i);
            if(params[0].getUserName().equals(userObj.getUserName())){
                successCheck = false;
                break;
            }
            else if (params[0].getEmail().equals(userObj.getEmail())){
                successCheck = false;
                break;
            } else{
                successCheck = true;
                break;
            }
        }
    } catch (JSONException e) {
        e.printStackTrace();
    }

    return successCheck;
}

@Override
protected void onPostExecute(Boolean result){
    if(successCheck)
    {
        //userCtrl.SignupUser(userobject);
        Log.d("Check","Ran Success");
        Toast.makeText(lcontext, "Success", Toast.LENGTH_SHORT).show();
    }
else {
        Log.d("Check","Ran Fail");
        Toast.makeText(lcontext, "Failed", Toast.LENGTH_SHORT).show();
    }
}

@Override
protected void onProgressUpdate(Integer... progress) {

}

最佳答案

是因为AsyncTask ,顾名思义,是一个异步任务。您需要在 SignupAsyncTask 类中测试结果。

将逻辑添加到您的 AsyncTask onPostExecute():

@Override
protected void onPostExecute(Boolean result){
  if(result == false){
    // Process if false
  } else if(result == true){
    // Process if true
  }
}

因为您无法从 SignupAsyncTask 访问 UI 线程(您的类不是调用者类的成员类),您需要在调用者类中定义一个接口(interface)作为监听器机制以接收来自 AsyncTask 的结果。因此,每当数据发生变化时,它都会通知实现该接口(interface)的调用者。

类似于:

public interface OnSuccessCheckReceived{
  void onSuccessCheckReceived(boolean isSuccess);
}

然后将回调接口(interface)添加到 SignupAsyncTask:

public class SignupAsyncTask extends AsyncTask<User, Integer, Boolean> {
  ...

  OnSuccessCheckReceived callBack;
  public SignupAsyncTask(){}

  public SignupAsyncTask(Context context, OnSuccessCheckReceived callBack){
    this.context = context;
    this.callBack = callBack;
  }

  ...

  @Override
  protected void onPostExecute(Boolean result){
    //if(result == false){
    //  // Process if false
    //  callBack.onSuccessCheckReceived(false); // Tell the caller 
    //} else if(result == true){
    //  // Process if true
    //}

    // a more compact code
    callBack.onSuccessCheckReceived(result); // Tell the caller 
  }

然后你需要为你的调用者类实现监听器接口(interface)。 像这样的东西:

public class YourCallerActivity implements OnSuccessCheckReceived {
  ...
  @Override 
  public void onSuccessCheckReceived(boolean isSuccess) {
    if(isSuccess){
        Toast.makeText(getBaseContext(), "Failed", Toast.LENGTH_SHORT).show();
    } else {
        Toast.makeText(getBaseContext(), "Success", Toast.LENGTH_SHORT).show();
    }
  }
  ...
}

然后你必须调用你的 AsyncTask:

// this is pointing to your implemented interface.
new SignupAsyncTask(getBaseContext(), this).execute(userModel); 

建议,

如果您不向 AsyncTask 添加 context 会更好,因为当您的应用终止并且 AsyncTask 尚未完成其工作时,您的 AsyncTask 将抛出错误,因为它指向的先前上下文已经消失。

因此您需要将 SignupAsyncTask 构造函数更改为:

public SignupAsyncTask(OnSuccessCheckReceived callBack){
  //this.context = context; Remove this.
  this.callBack = callBack;
}

并调用 SignupAsyncTask:

new SignupAsyncTask(this).execute(userModel);

更新

正如@trooper 指出的那样,您需要更改:

@Override
protected void onPostExecute(Double result){

}

@Override
protected void onPostExecute(Boolean result){

}

所以要告诉调用者类,你需要告诉结果:

@Override
protected void onPostExecute(Boolean result){
  // This is a more compact code that your previous code.
  callBack.onSuccessCheckReceived(result); // Tell the caller 
}

基于您的 AsyncTask 中的其他签名。

关于java - Android AsyncTask 保持返回相反的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40122874/

相关文章:

java - Android 上的 Kivy,在空对象引用上发生 JVM 异常 : Attempt to invoke virtual method . ..

java - 如何在 Java 中访问和使用 PC Direct WiFi?

android - android服务是单例吗?

java - 带有适配器 ""的 ViewPager 需要 AsyncTask 中的 View id

java - 异步任务流程

java - Bck2Brwsr 与 JavaFX 一起?

android - 如何在 Android 应用程序的数据库中存储指纹数据以及用户名、图像、电子邮件等

android - 在不同的 Activity 中使用 findviewbyid

java - onPostExecute 不允许我创建 Toast 消息

java - 删除数组列表中相交的值