将 AsyncTask 重置为多次执行
Reset AsyncTask to multiple execution
有什么方法可以多次使用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;
我是这样调用Task的(我的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()
) Whosebug Thread 来重置 AsyncTask
,但它对我不起作用。当我尝试在 Login
class:
中做这样的事情时
private void selfRestart(){
Login task = new Login(context, listener);
task.execute("");
//im calling it in onPostExecute()
}
我的 android 应用崩溃了。我的问题是,重置在不同文件中实现的 AsyncTask
和我的 Activity
class 的最佳方法是什么?或者也许有更好的方法使 Login
activity 比在 AsyncTask
?
中实现整个登录逻辑更好
编辑:
Logcat:
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){ }
}
,但是不,你 不是 "calling" 你的任务。您正在创建任务的单个实例,并设置一个事件处理程序来执行该任务——那个特定的实例——只要 loginButton
被单击。由于每个 AsyncTask
实例可能只执行一次,因此第二次单击登录按钮时将失败(如果不是更早,则出于其他原因)。
你也说,
I Read, that we can reset AsyncTask by making new AsyncTask
(Task = new Login()
)
,但是 no,它不会重置任何东西,实际上 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
,因此可能是包含 class 的实例变量,而不是您的代码所在方法的局部变量摘录。
但是,您最好的前进方式很可能是完全放弃 AsyncTask
。当你这样使用它时:
login.execute(email, password).get();
...你破坏了整个目的。您正在使运行该线程的线程阻塞直到任务完成(这就是 AsyncTask::get
对于 的 ),因此该任务实际上是同步的。如果那是您的要求,那么您应该更直接地完成所需的工作,而不是将其包装在 AsyncTask
.
中
有什么方法可以多次使用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;
我是这样调用Task的(我的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()
) Whosebug Thread 来重置 AsyncTask
,但它对我不起作用。当我尝试在 Login
class:
private void selfRestart(){
Login task = new Login(context, listener);
task.execute("");
//im calling it in onPostExecute()
}
我的 android 应用崩溃了。我的问题是,重置在不同文件中实现的 AsyncTask
和我的 Activity
class 的最佳方法是什么?或者也许有更好的方法使 Login
activity 比在 AsyncTask
?
编辑:
Logcat:
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 (myActivity.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){ } }
,但是不,你 不是 "calling" 你的任务。您正在创建任务的单个实例,并设置一个事件处理程序来执行该任务——那个特定的实例——只要 loginButton
被单击。由于每个 AsyncTask
实例可能只执行一次,因此第二次单击登录按钮时将失败(如果不是更早,则出于其他原因)。
你也说,
I Read, that we can reset AsyncTask by making new
AsyncTask
(Task = new Login()
)
,但是 no,它不会重置任何东西,实际上 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
,因此可能是包含 class 的实例变量,而不是您的代码所在方法的局部变量摘录。
但是,您最好的前进方式很可能是完全放弃 AsyncTask
。当你这样使用它时:
login.execute(email, password).get();
...你破坏了整个目的。您正在使运行该线程的线程阻塞直到任务完成(这就是 AsyncTask::get
对于 的 ),因此该任务实际上是同步的。如果那是您的要求,那么您应该更直接地完成所需的工作,而不是将其包装在 AsyncTask
.