我正在寻找解决问题的方法。
我在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();
感谢帮助
答案 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();
}
}
}