我在 Android Studio 中遇到 AsyncTask 问题。我想做的是在创建新用户之前,我正在检查用户名和电子邮件是否存在于我的数据库中。这是我调用创建 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 打印出“失败”。
然后,当我尝试使用另一条重复记录时,它不会插入数据库,因为我将我的用户名和电子邮件设置为 UNIQUE,但 toast 打印出“成功”。
和我的代码逻辑相反的操作。有任何想法吗?
提前致谢
编辑
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) {
}
最佳答案
是因为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 线程(您的类不是调用者类的成员类),您需要在调用者类中定义一个接口(interface)作为监听器机制以接收来自 AsyncTask 的结果。因此,每当数据发生变化时,它都会通知实现该接口(interface)的调用者。
类似于:
public interface OnSuccessCheckReceived{
void onSuccessCheckReceived(boolean isSuccess);
}
然后将回调接口(interface)添加到 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
}
然后你需要为你的调用者类实现监听器接口(interface)。 像这样的东西:
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 添加 context 会更好,因为当您的应用终止并且 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 中的其他签名。
关于java - Android AsyncTask 保持返回相反的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40122874/