问题:
Android开发在使用AsyncTask做计算线程的时候,使用了单例模式获取task的对象(以保证下一个Activtiy获取的是同一个对象);
在从下一个Activtity回到原来Actitvity的时候,不做任何操作,直接点击“运算”按钮,会出现如题的错误。
错误Log如下:
E/AndroidRuntime(10626): FATAL EXCEPTION: main
E/AndroidRuntime(10626): Process: com.jrdcom.perf, PID: 10626
E/AndroidRuntime(10626): java.lang.IllegalStateException: Cannot execute task: the task has already been executed (a task can be executed only once)
E/AndroidRuntime(10626): at android.os.AsyncTask.executeOnExecutor(AsyncTask.java:583)
E/AndroidRuntime(10626): at android.os.AsyncTask.execute(AsyncTask.java:539)
E/AndroidRuntime(10626): at com.jrdcom.perf.LogListActivity$2.onClick(LogListActivity.java:150)
E/AndroidRuntime(10626): at android.view.View.performClick(View.java:4781)
E/AndroidRuntime(10626): at android.view.View$PerformClick.run(View.java:19874)
E/AndroidRuntime(10626): at android.os.Handler.handleCallback(Handler.java:739)
E/AndroidRuntime(10626): at android.os.Handler.dispatchMessage(Handler.java:95)
E/AndroidRuntime(10626): at android.os.Looper.loop(Looper.java:135)
E/AndroidRuntime(10626): at android.app.ActivityThread.main(ActivityThread.java:5329)
E/AndroidRuntime(10626): at java.lang.reflect.Method.invoke(Native Method)
E/AndroidRuntime(10626): at java.lang.reflect.Method.invoke(Method.java:372)
E/AndroidRuntime(10626): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:940)
E/AndroidRuntime(10626): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:735)
I/ActivityManager( 772): handleApplicationCrash
原因:
AsyncTask 本身设计如此,不适合多任务同时运行,execute()只能被执行一次(同一个对象);如过要一次执行多个任务用executeOnExecutor()。
解决方式:
1. 不使用单例,每次执行的时候会 new AsyncTask 。自然不会产生此问题。 ---一般用这种方法
2. 计算线程换用 Thread + Handler实现。
3. 在原Activity 的onResume()函数中加上对Task对象的置空处理即可,从而每次退回到原Activity并从新计算的时候会有个新的对象。
Task类中:
public static ParseDataTaskPresenter getInstance() {
if (mParseDataTaskPresenter == null) {
mParseDataTaskPresenter = new ParseDataTaskPresenter();
}
return mParseDataTaskPresenter;
}
public static void flushParseDataTaskPresenter() {
if (mParseDataTaskPresenter != null) {
mParseDataTaskPresenter = null;
}
}
原Activity :
@Override
protected void onResume() {
Logger.d("loglist onResume do");
ParseDataTaskPresenter.flushParseDataTaskPresenter();
super.onResume();
}