我在活动首次启动时运行了asyncTask,然后如果网络连接不可用,那么我有一个刷新按钮,尝试运行asyncTask再试一次。但我得到一个调试错误说这个..
07-29 18:14:21.290: ERROR/AndroidRuntime(9080): FATAL EXCEPTION: main
07-29 18:14:21.290: ERROR/AndroidRuntime(9080): java.lang.IllegalStateException: Cannot execute task: the task has already been executed (a task can be executed only once)
07-29 18:14:21.290: ERROR/AndroidRuntime(9080): at android.os.AsyncTask.executeOnExecutor(AsyncTask.java:541)
07-29 18:14:21.290: ERROR/AndroidRuntime(9080): at android.os.AsyncTask.execute(AsyncTask.java:499)
07-29 18:14:21.290: ERROR/AndroidRuntime(9080): at com.fttech.gameIT.MainMenu$1.onClick(MainMenu.java:90)
无论如何都要运行两次?
答案 0 :(得分:72)
只需创建另一个实例并执行它。
答案 1 :(得分:33)
就像线程一样,AsyncTask
s无法重用。每次要运行一个实例时,都必须创建一个新实例。
答案 2 :(得分:16)
你永远不能再次执行一个线程,而不是Java
,而不是任何其他语言,一旦线程完成run()
方法,你就无法重启它,这就是你得到的原因IllegalStateException
。
然而,您仍然可以在该线程上调用方法,但它们将在不同线程上调用 NOT 的线程上运行。因此,您必须创建一个新的。
答案 3 :(得分:5)
您不能多次运行AsyncTask的相同实例。 假设你有一个名为MyAsyncTaks的AsyncTask,你打算做这样的事情,
MyAsyncTask myAsyncTask = new MyAsyncTaks();
myAsyncTask.execute(); // Works as expected
.
.
.
.
myAsyncTask.execute(); // This will throw you exception
原因是,一个线程一旦完成其“运行”方法,就无法分配另一个任务。这里,在第一次调用execute()时,你的AsyncTask开始运行 完成工作后,线程就会运行。当然,下一次调用execute()会抛出异常。
不止一次运行此操作的最简单方法是创建MyAsyncTaks的新实例并在其上调用execute。
MyAsyncTask myAsyncTask = new MyAsyncTaks();
myAsyncTask.execute(); // Works as expected
.
.
.
MyAsyncTask myAsyncTask2 = new MyAsyncTaks();
myAsyncTask2.execute(); // Works as expected
虽然这里不需要提及,但必须注意发布Android SDK版本Honeycomb,如果你一次运行多个AsyncTask,它们实际运行 顺序。如果要以parallally方式运行它们,请改用executeOnExecutor。
答案 4 :(得分:4)
只需像新的asyncTask()一样进行新的调用.execute();您必须创建一个新对象才能重新启动该任务。
答案 5 :(得分:3)
我只是创建了asynctask然后创建了一个runnable,它创建了asynctask的新实例。然后,您可以反复向处理程序提交runnable。
class MyAsyncTask extends AsyncTask<String, Void, String>{ ...}
Runnable myRunner = new Runnable(){
public void run() {
new MyAsyncTask ().execute(...);
}};
myHandler.post(myRunner);
答案 6 :(得分:0)
我创建了一个类型为ProgressUpdater的Arraylist(扩展AsyncTask的类的名称)并将实例添加到其中(在按钮的onClick中)。因此,您可以在需要时执行和取消这些任务。
public class MainActivity extends Activity {
ProgressBar progress;
ProgressUpdater task;
ArrayList<ProgressUpdater> pu = new ArrayList<MainActivity.ProgressUpdater>();
int count = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
progress = (ProgressBar) findViewById(R.id.progress);
}
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn:
task = new ProgressUpdater();
pu.add(task);
count++;
pu.get(count - 1).execute(0);
System.out.println("task" + task);
// task.execute(10);
break;
case R.id.btnCancel:
if (count >= 0) {
pu.get(count - 1).cancel(true);
pu.remove(count - 1);
count--;
}
// task.cancel(true);
break;
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
private class ProgressUpdater extends AsyncTask<Integer, Integer, Void> {
@Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
progress = (ProgressBar) findViewById(R.id.progress);
progress.setMax(100);
}
@Override
protected Void doInBackground(Integer... params) {
// TODO Auto-generated method stub
int start = params[0];
for (int i = start; i <= 100; i++) {
try {
boolean cancelled = isCancelled();
if (!cancelled) {
publishProgress(i);
SystemClock.sleep(100);
}
} catch (Exception e) {
e.printStackTrace();
}
}
return null;
}
@Override
protected void onPostExecute(Void result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
Log.v("Progress", "Finished");
}
@Override
protected void onCancelled() {
// TODO Auto-generated method stub
super.onCancelled();
progress.setMax(0);
}
@Override
protected void onProgressUpdate(Integer... values) {
// TODO Auto-generated method stub
super.onProgressUpdate(values);
progress.setProgress(values[0]);
}
}
}
答案 7 :(得分:0)
LeoAsyncTask leoAsyncTaskGeneric;
public void onClick_AsyncTask(View view) {
LeoAsyncTask leoAsyncTaskInner = new LeoAsyncTask();
leoAsyncTaskInner.execute();
leoAsyncTaskGeneric=leoAsyncTaskInner;
}
/ **如果你在AsyncTask类的内存中创建一个空间作为泛型,那么你可以在onClick方法中创建同一个类的实例,并且等于,所以每次按下onClick你都会使用Class AsyncTask的新实例,它不会给你带来问题 * /
答案 8 :(得分:0)
当您按下按钮然后再次执行时,您可以取消asyncTask。
OnClic方法:
asyncTask.cancel();
AsyncTask asyncTask = new AsyncTask();
asyncTask.execute();
答案 9 :(得分:0)
这解决了我的问题:
public class MainActivity extends AnimationActivity {
MyAsyncTasks asyncTasks = new MyAsyncTasks();
@BindView(R.id.refresh_btn)
Button refreshBtn;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setUnbinder(ButterKnife.bind(this)); // ButterKnife usage
syncTasks(); // run asyncTasks on activity start
refreshBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
syncTasks(); // run asyncTasks on button click
}
});
}
private void syncTasks() {
try {
if (asyncTasks.getStatus() != AsyncTask.Status.RUNNING){ // check if asyncTasks is running
asyncTasks.cancel(true); // asyncTasks not running => cancel it
asyncTasks = new MyAsyncTasks(); // reset task
asyncTasks.execute(); // execute new task (the same task)
}
} catch (Exception e) {
e.printStackTrace();
Log.e("MainActivity_TSK", "Error: "+e.toString());
}
}
}
答案 10 :(得分:0)
您可以这样做:
private MyAsyncTask createAsyncTask(){
if (myAsyncTask == null){
return myAsyncTask = new MyAsyncTask();
}
myAsyncTask.cancel(true);
return myAsyncTask = new MyAsyncTask();
}
然后您可以使用它:
createAsyncTask().execute();
这每次都会成为后台任务的新实例。
答案 11 :(得分:0)
@ coder_For_Life22我认为答案来晚了,无论如何您都可以做到
@Override
protected void onPostExecute(Void a) {
myAsyncTask=new MyAsyncTask();
}
为了在执行后启动新的AsyncTask :)
答案 12 :(得分:-1)
线程规则
有关详细信息,请查看此link