How to run the same asynctask more than once?

前端 未结 12 1984
难免孤独
难免孤独 2020-12-01 03:32

I have my asyncTask run when the activity first starts, then if network connectivity is not available then i have a refresh button that tries to run the asyncTask to try aga

相关标签:
12条回答
  • 2020-12-01 03:51

    I created an Arraylist of type ProgressUpdater(Name of class which extends AsyncTask) and added the instances into it(in the onClick of a button). So you can execute and cancel these task when needed.

    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]);
        }
    
    }
    

    }

    0 讨论(0)
  • 2020-12-01 03:54

    This solved my problem:

    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());
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-01 03:55

    I just create the asynctask then create a runnable that creates new instances of the asynctask. Then you can submit your runnable over and over again to the handler.

    class MyAsyncTask extends AsyncTask<String, Void, String>{ ...}
    
    Runnable myRunner = new Runnable(){
         public void run() {
            new MyAsyncTask ().execute(...);
    }};
    myHandler.post(myRunner);
    
    0 讨论(0)
  • 2020-12-01 03:56

    You cannot run same instance of an AsyncTask more than once. Let's assume you have an AsyncTask named MyAsyncTaks and you intend to do something like this,

        MyAsyncTask myAsyncTask = new MyAsyncTaks();
        myAsyncTask.execute(); // Works as expected
        .
        .
        .
        .
        myAsyncTask.execute(); // This will throw you exception
    

    The reason for this is, a thread once finishes its 'run' method, cannot be assigned another task. Here, on the first invocation of execute(), your AsyncTask started running and after doing its job, the thread comes out of run. Naturally, next invocation of execute() will throw you exception.

    The simplest way to run this more than once is to create a new instance of MyAsyncTaks and call execute on that.

        MyAsyncTask myAsyncTask = new MyAsyncTaks();
        myAsyncTask.execute(); // Works as expected
        .
        .
        .
        MyAsyncTask myAsyncTask2 = new MyAsyncTaks();
        myAsyncTask2.execute(); // Works as expected
    

    Though its not needed to be mentioned here, one must be aware that post Android SDK version Honeycomb, if your run more than one AsyncTask at once, they actually run sequentially. If you want to run them parallally, use executeOnExecutor instead.

    0 讨论(0)
  • 2020-12-01 03:57

    Just like threads, AsyncTasks can't be reused. You have to create a new instance every time you want to run one.

    0 讨论(0)
  • 2020-12-01 03:58

    You can never execute a thread again, not in Java, not in any other language, once the thread is done with the run() method, you cannot restart it, which is why you are getting the IllegalStateException.

    You can however still call the methods on that thread but they will run on the thread that is calling them NOT on a different thread. Therefore you will have to create a new one.

    0 讨论(0)
提交回复
热议问题