从onPostExecute和doInBackground返回布尔值

时间:2019-01-24 12:22:57

标签: java android android-asynctask

我正在寻找解决问题的方法。

我在AsyncTask中呼叫Activity

login.execute(emailText.getText().toString(), passwordText.getText().toString());

在登录类中,我检查用户是否存在。

public class Login extends AsyncTask<String, Boolean, Void> {

public Login(Application application){
    repository = new Repository(application);
}

@Override
protected Boolean doInBackground(String... body){
    try {
        user = repository.getUser(body[0], body[1]);
        if (user != null)
            return true; //wont work
        else {
            return false;
        }
    }
    catch(Exception e){
        return null;
    }
}

protected void onPostExecute(Long result) {
   //i want to have bool value here that i will see in my activity
}

我的问题是,如果条件匹配,如何从bool获取AsyncTask的值?是否有可能这样调用方法?

boolean valid = login.execute();

感谢帮助

4 个答案:

答案 0 :(得分:1)

构建您的asyncTask,例如:

public class Login extends AsyncTask<Void, Void, Void> {

private boolean valid;

@Override
public Void doInBackground(Void... records) {
    // do work here
    user = repository.getUser(body[0], body[1]);
    if (user != null)
       valid = true;
    else
       valid = false;
    return null;
}

@Override
protected void onPostExecute(Void result) {
    callMyMethodWithTheUpdatedValue(valid);
}

}

答案 1 :(得分:1)

像下面的代码一样更改您的代码:

public class Login extends AsyncTask<String, Boolean, Boolean> {

public Login(Application application){
    repository = new Repository(application);
}

@Override
protected Boolean doInBackground(String... body){
    try {
        user = repository.getUser(body[0], body[1]);
        if (user != null)
            return Boolean.TRUE; //wont work
        else {
            return Boolean.FALSE;
        }
    }
    catch(Exception e){
        return Boolean.FALSE;
    }
}

protected void onPostExecute(Boolean result) {
   //i want to have bool value here that i will see in my activity
   Log.e("POST_EXECUTE", "" + result);
}

答案 2 :(得分:1)

onPostExecute()参数类型更改为Boolean,然后告诉谁会对结果感兴趣。

对于这最后一部分,您可以有一个接口,并让某个人(感兴趣的类)实现它。

public class Login extends AsyncTask<String, Boolean, Boolean> {

  private LoginListener listener;

  public Login(Application application, LoginListener listener){
    repository = new Repository(application);
    this.listener = listener;
  }

  @Override
  protected Boolean doInBackground(String... body){
    try {
        user = repository.getUser(body[0], body[1]);
        if (user != null)
            return true; //wont work
        else {
            return false;
        }
    }
    catch(Exception e){
        return null;
    }
  }

  protected void onPostExecute(Boolean result) {
   listener.onLoginPerformed(result)
  }



  public static interface LoginListener{
    public void onLoginPerformed(Boolean result);
  }
}

然后假设您希望MainActivity在登录时做出反应:

public class MainActivity extends AppCompatActitvity implements LoginListener{
    ....
    // When you create the Login object, in onCreate() for example:
    // new Login(application, this); // this is the activity acting as listener...

    @Override public void onLoginPerformed(Boolean result){
        // do what you want to do with the result in Main Activity
    }

}

答案 3 :(得分:1)

AsyncTask的想法不是“获取”结果,而是在不阻止UI的情况下在后台进行某些操作。您的方法将阻止UI线程,直到服务器返回响应为止,该应用将被阻止,如果该状态保持5秒钟以上,则用户将看到ANR

但要回答您的问题: 为了从AsyncTask中获得布尔结果,您需要扩展正确的类,在您的情况下,它是:AsyncTask<String, Void, Boolean>,因为AsyncTask类型如下:

  

异步任务使用的三种类型如下:

     

Params (参数),即在执行时发送给任务的参数的类型。

     

进度,是后台计算过程中发布的进度单位的类型。

     

结果,是后台计算结果的类型。

为回答您的问题,您的代码将为:

//USAGE
Login l = new Login();
Boolean valid = l.execute("user", "pass").get(); 
/* but the UI thread will be 
blocked, meaning the following code will not be executed until the variable 
valid is populated */ 

//AsyncTask
public class Login extends AsyncTask<String, Void, Boolean> {

public Login(Application application){
    repository = new Repository(application);
}

@Override
protected Boolean doInBackground(String... strings){
    try {
        user = repository.getUser(strings[0], strings[1]);
        if (user != null)
            return true; //wont work
        else {
            return false;
        }
    }
    catch(Exception e){
        return null;
    }
}

protected void onPostExecute(Boolean result) {
   // this method is no longer needed since you will get the result directly 
   // from the doInBackground method

}

对于实际可行的解决方案也不适用: 我建议每次用户想要登录该应用程序时,都应显示一个progressDialog窗口,通知用户它必须执行一项耗时的任务,并在该过程完成后将状态通知用户。 为此,请使用以下代码:

//USAGE
   @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_test);
        Login l = new Login();
        l.execute("user", "pass"); 
        /* but the UI thread will be 
        blocked, meaning the following code will not be executed until the                             
        variable valid is populated */
    }

public void userLoggedIn() {
    // do something when a user loggs in sucessfully
}

public void wrongCredentials() {
    // alert the user that he didn't put in the correct credentials
}

//AsyncTask
public class Login extends AsyncTask<String, Void, Boolean> {


    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        // show a dialog window here when the AsyncTask starts
    }

    @Override
    protected Boolean doInBackground(String... strings){
        try {
            user = repository.getUser(strings[0], strings[1]);
            if (user != null)
                return true; //wont work
            else {
                return false;
            }
        }
        catch(Exception e){
            return null;
        }
    }

       @Override
    protected void onPostExecute(Boolean aBoolean) {
        super.onPostExecute(aBoolean);
        // dismiss the dialog window here after the AsyncTask finishes
        if (aBoolean) {
            userLoggedIn();
        } else {
            wrongCredentials();
        }
    }
}