gpt4 book ai didi

java - 将 AsyncTask 重置为多次执行

转载 作者:行者123 更新时间:2023-12-02 10:20:54 25 4
gpt4 key购买 nike

有没有办法多次使用AsyncTask.execute()

我使用AsyncTask来检查User是否存在于我的房间数据库中。

我的Login.class看起来像这样:

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

public Login(Context context, LoginListener listener){
db = ApplicationDatabase.getDatabase(context); //i get Room here
this.context = context; //context of app
this.listener = listener; //my interfece for observe Boolean, works ok
}

@Override
protected Boolean doInBackground(String... body){
try {
user = db.userDao().getUser(body[0], body[1]);
if (user != null)
return Boolean.TRUE; //we find user with credentials
else {
return Boolean.FALSE; //we not find user with that credentials (from body)
}
}
catch(Exception e){
return null;
}
}

protected void onPostExecute(Boolean result) {
listener.onLoginPerformed(result); //Boolen to activity
selfRestart(); //i want to restart task here
}

private void selfRestart(){
//maybe something to do here? its my own method
}

private ApplicationDatabase db;
private User user;
private LoginListener listener;
private Context context;

我以这种方式调用任务(我的Activity.class):

login = new Login(getApplicationContext(), this); 
//this is an interface that i implements in Activity definition

loginButton.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v){
//execute() here, i cuted some not necesery code from here
try {
// im using get because i want to get valu from AsyncTask
login.execute(email, password).get();
}
catch(Exception e){ }
}

我读到,我们可以通过创建新的 AsyncTask (Task = new Login()) StackOverflow Thread 来重置 AsyncTask但它对我不起作用。当我尝试在我的 Login 类中进行类似的操作时:

private void selfRestart(){
Login task = new Login(context, listener);
task.execute("");
//im calling it in onPostExecute()
}

我的 Android 应用程序崩溃了。我的问题是,重置在不同文件中实现的 AsyncTask 的最佳方法是什么,然后是我的 Activity 类?或者也许有比在 AsyncTask 中实现整个登录逻辑更好的方法来创建 Login Activity ?

编辑:

日志猫:

2019-01-24 15:45:31.407 1048-1048/com.example.admin.keystroke_dynamics E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.admin.keystroke_dynamics, PID: 1048
java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.lang.Boolean.booleanValue()' on a null object reference
at com.example.admin.keystroke_dynamics.Activities.LoginActivity.onLoginPerformed(LoginActivity.java:62)
at com.example.admin.keystroke_dynamics.Login.onPostExecute(Login.java:38)
at com.example.admin.keystroke_dynamics.Login.onPostExecute(Login.java:14)
at android.os.AsyncTask.finish(AsyncTask.java:692)
at android.os.AsyncTask.-wrap1(AsyncTask.java)
at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:709)
at android.os.Handler.dispatchMessage(Handler.java:105)
at android.os.Looper.loop(Looper.java:156)
at android.app.ActivityThread.main(ActivityThread.java:6523)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:942)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:832)

最佳答案

你说,

I call Task in this way (my Activity.class):

login = new Login(getApplicationContext(), this); 
//this is an interface that i implements in Activity definition

loginButton.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v){
//execute() here, i cuted some not necesery code from here
try {
// im using get because i want to get valu from AsyncTask
login.execute(email, password).get();
}
catch(Exception e){ }
}

,但是不,您不是那样“调用”您的任务。您正在创建该任务的单个实例,并设置一个事件处理程序,每当单击 loginButton 时,该事件处理程序就会执行该任务(即特定实例)。由于每个 AsyncTask 实例只能执行一次,因此第二次单击登录按钮时将会失败(如果不是更早,则由于某些其他原因)。

你还说,

I Read, that we can reset AsyncTask by making new AsyncTask (Task = new Login())

,但是,这不会重置任何东西,并且实际上AsyncTask对象无法重置。您读到的建议是用新实例替换使用的AsyncTask。实例化一个新的 AsyncTask 对其他任务没有特别的影响。如果您想采用这种方法,那么它可能看起来像这样:

loginButton.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v){
Login myLoginTask = login; // keep a reference to the current task
login = new Login(... arguments ...); // create a new task for the next click

try {
// use the original task
myLoginTask.execute(email, password).get();
}
catch(Exception e){ }
}

该特定实现要求 login 为非 final,因此可能是包含类的实例变量,而不是代码所在方法的局部变量摘录。

但是,您最好的前进方式很可能是完全放弃 AsyncTask。当你像这样使用它时:

                login.execute(email, password).get();

...你破坏了整个目的。您正在使运行该线程的线程阻塞,直到任务完成(这就是 AsyncTask::get 的作用),因此该任务实际上是同步的。如果这就是您所需要的,那么您应该更直接地完成想要的工作,而不是将其包装在 AsyncTask 中。

关于java - 将 AsyncTask 重置为多次执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54348829/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com