调试时,java onPostExecute()与doInBackground()无关
我在AsyncTask
类中的onPostExecute()
方法有问题
我有一个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);
}
我的问题是,为什么当我第一次单击按钮时,func返回Boolean.TRUE
,但在SignupActivity
{false
(注册表单不退出,但用户被添加到数据库),但当我第二次单击注册按钮时,ofc注册失败(因为我们在几秒钟前创建了新用户),但signupValid
更改为true
,注册表单通过?我需要点击SignupButton
两次才能最终退出表单。感谢您在我的代码中发现错误
编辑:
我用Progress Dialog
替换了.get()
以阻止UI,但现在我甚至在AsyncTask
注册之前就用无效形式得到了Toast
。尽管如此,在第一次单击中signupValid
是假的,即使从doInBackground()
我得到TRUE
,在第二次单击中AsyncTask
返回FALSE
,但是signupValid
更改为true
我的用户道:
@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;
# 1 楼答案
如果我正确理解了这个问题,那么有一个竞争条件使得
SignupActivity
在Signup
任务执行完成之前触发toast。因此:而这些线:
应该是
listener
的一部分(现在看来,这些行是在异步任务完成之前执行的)我想澄清一下: