Android AsyncTask保持返回相反的值

时间:2016-10-19 05:28:21

标签: java android android-asynctask

我在Android Studio上遇到了AsyncTask的问题。我想要做的是在创建新用户之前,我正在检查我的数据库中是否存在用户名和电子邮件。这是我调用create 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&#39; Failed&#39;。

然后,当我尝试使用另一个重复记录时,它不会插入到数据库中,因为我将用户名和电子邮件设置为UNIQUE但是吐司正在打印出来&#39;成功&#39;。

它的操作方式与我的代码逻辑相反。有任何想法吗?

提前致谢

修改

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) {

}

3 个答案:

答案 0 :(得分:2)

因为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线程(其中您的类不是调用者类的成员类),您需要在调用者类中将接口定义为侦听器机制,以从AsyncTask接收结果。因此,只要数据发生变化,它就会通知实现该接口的调用者。

类似的东西:

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

然后将回调接口添加到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 
  }

然后,您需要为调用者类实现侦听器接口。 类似的东西:

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 ,则会更好,因为当您的应用终止并且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中的其他签名。

答案 1 :(得分:1)

将您的逻辑放在onPostExecute()

protected void onPostExecute(Boolean result){
    if(successCheck){
        Toast.makeText(getBaseContext(), "Success", Toast.LENGTH_SHORT).show();
    } else {
        Toast.makeText(getBaseContext(), "Failed", Toast.LENGTH_SHORT).show();
    }
}

AsyncTask 异步执行,即它不在主线程上运行。它产生一个称为Worker thread的独立线程,执行其逻辑,然后将结果发回到主线程。

编辑1

更改您的代码如下:

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;
    User user = null;

    public SignupAsyncTask(){}

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

    @Override
    protected Boolean doInBackground(User... params) {
        try {
            user = params[0];
            list = userCtrl.getAllUser();
            for(int i = 0; i < list.size(); i++){
                User userObj = list.get(i);
                if(user.getUserName().equals(userObj.getUserName())){
                    successCheck = false;
                    break;
                }
                else if (user.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(result){
            Toast.makeText(getBaseContext(), "Success", Toast.LENGTH_SHORT).show();
            //Call SignupUser Code Here...
            if(user != null) {
                userCtrl.SignupUser(user);   
            }
        } else {
            Toast.makeText(getBaseContext(), "Failed", Toast.LENGTH_SHORT).show();
        }
    }

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

    }
}

答案 2 :(得分:0)

请修改您的代码

    private ArrayList<User> list;
        private DB_User userCtrl;
        private Context context;
        private SendResponse mRes;

        public SignupAsyncTask(Context context,SendResponse res){
            this.context = context;
            userCtrl = new DB_User();
            list = new ArrayList<User>();
            mRes = res;
        }

        @Override
        protected Boolean doInBackground(User... params) {
            try {
                list = userCtrl.getAllUser();
                for(User userObj:userCtrl.getAllUser()){
                    if(params[0].getUserName().equals(userObj.getUserName())
                            || params[0].getEmail().equals(userObj.getEmail()))
                       return false;
                }else{
                    userCtrl.SignupUser(params[0]);
                      return true;
}
            } catch (JSONException e) {
                e.printStackTrace();
                return false;
            }
                return true;
        }

        @Override
        protected void onPostExecute(Boolean result){


                //notify through interface to activity or fragment wherever you want to
                //mRes.sendResponse(result);
        }

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

        }