我在onPostExecute()
类中的AsyncTask
方法有问题。
我有一个 SignupActivity
:
public class SignupActivity extends AppCompatActivity implements SignupListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.signup_activity);
//new task, i pass context and interface to it
signup = new Signup(getApplicationContext(), this);
signupButon.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v){
if(validate()) {
try {
//new task every click
Signup newSignup = new Signup(signup);
//here start AsyncTask
newSignup.execute(name, email, password).get();
} catch (Exception e) {
Toast.makeText(ERROR);
}
// if sign up succes, == true;
if(signupValid) {
Toast.makeText(SUCCES);
finish();
} else {
Toast.makeText(ERROR);
}
}
}
});
}
// my own interface for getting result as bool from onPostExecute
@Override
public void onSignupPerformed(Boolean result){ this.signupValid = result; }
这实现了我的界面来捕获onPostExecute()
的结果:
public interface SignupListener{
void onSignupPerformed(Boolean result);
}
现在,我在代码中触发的 AsyncTask
:
public class Signup extends AsyncTask<String, Boolean, Boolean> {
public Signup(Context context, SignupListener listener){
db = ApplicationDatabase.getDatabase(context);
this.context = context;
this.listener = listener;
}
public Signup(Signup signup){
//constructor to make new task based on first task
db = signup.db;
context = signup.context;
listener = signup.listener;
}
protected Boolean doInBackground(String... body){
try {
user = db.userDao().getUser(body[0], body[1], body[2]);
if (user == null) {
// user is null, so we can add new one to DB
db.userDao().insertUser(new User(body[0], body[1], body[2]));
return Boolean.TRUE; //signup go good, return true
} else {
return Boolean.FALSE; //signup go bad, return false
}
} catch(Exception e) { }
return null;
}
protected void onPostExecute(Boolean result) {
//catching result from doInBackground
listener.onSignupPerformed(result);
}
我的问题是,为什么当我第一次单击按钮时,函数返回Boolean.TRUE
但在SignupActivity
signupValid
中的变量是false
(注册表单没有退出,而用户却是已添加到数据库中),但是当我第二次单击“注册”按钮时,ofc的注册失败(因为我们几秒钟前就创建了新用户),但是signupValid
更改为true
并通过了注册表单?我需要单击两次SignupButton
才能最终退出表单。感谢您在我的代码中发现错误
编辑:
我用.get()
替换了Progress Dialog
来阻止UI,但是现在我什至在Toast
进行注册之前就得到了AsyncTask
无效的表单。而且,即使我从signupValid
得到doInBackground()
,第一次单击TRUE
还是假的,第二次单击AsyncTask
返回FALSE
却是signupValid
更改为true
我的 UserDAO:
@Dao
public interface UserDao {
@Query("SELECT * FROM users WHERE email = :email AND password = :password AND username = :username")
User getUser(String username, String email, String password);
}
和 ApplicationDatabase:
public abstract class ApplicationDatabase extends RoomDatabase {
public abstract UserDao userDao();
public static ApplicationDatabase getDatabase(final Context context){
if(INSTANCE == null){
synchronized (ApplicationDatabase.class){
if(INSTANCE == null){
INSTANCE = Room.databaseBuilder(context.getApplicationContext(), ApplicationDatabase.class, "database").build();
}
}
}
return INSTANCE;
}
private static volatile ApplicationDatabase INSTANCE;
答案 0 :(得分:1)
如果我正确理解了该问题,则有一种竞赛条件会导致SignupActivity
在执行Signup
任务之前先烤面包。因此:
signupButon.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v){
if(validate()) {
try {
//new task every click
Signup newSignup = new Signup(signup);
//here start AsyncTask
newSignup.execute(name, email, password).get();
} catch (Exception e) {
Toast.makeText(ERROR);
}
}
}
});
这些行:
// if sign up succes, == true;
if(signupValid) {
Toast.makeText(SUCCES);
finish();
} else {
Toast.makeText(ERROR);
}
应该是listener
的一部分(现在看来这些行是在异步任务完成之前执行的)
为了澄清自己:
@Override
public void onSignupPerformed(Boolean result)
{
if(result) {
Toast.makeText(SUCCES);
finish();
} else {
Toast.makeText(ERROR);
}
}