I make an application on Android. I try to make a call to run the Asynctask thread in a Asynctask , but the problem is that when the loop is executed, the thread does not stop and the code continues to run before the thread is completed.

For example:

 for (int i =0; i<array.size; i++) { ......(код) new MyAsynctask().execute(); ......(код) } Intent intent = new Intent(this, Activity2.class); startActivity(intent); 

where Asynctask itself:

  class MyAsynctask extends AsyncTask<Void, Void, Void> { @Override protected void onPreExecute() { super.onPreExecute(); pDialog = new ProgressDialog(MainActivity.this); pDialog.setMessage("Loading!!!"); pDialog.setCancelable(false); pDialog.show(); } @Override protected Void doInBackground(Void... arg0) { ........... (вся тяжелая работа) } } @Override protected void onPostExecute(Void result) { super.onPostExecute(result); if (pDialog.isShowing()) pDialog.dismiss(); } 

With this code, the async is called in a loop, it starts to execute and immediately after it, the code in the UI starts to be executed even if the asynccusc has not finished its work. I want the asinkt to be executed to the end, then the subsequent code will be executed sequentially and after going through (completing) the whole cycle, a transition to another activation was performed. This can be done with the get () method.

  new MyAsynctask().execute().get(); 

everything seems to work this way, but the problem is that the UI stream stops then until the Asynctask thread ends. That is, no action takes place on the display (I need the Progress Bar to spin).

Write:

 Intent intent = new Intent(this, Activity2.class); startActivity(intent); 

in onPostExecute(); also not suitable as Asynctask is called several times in a loop. And I need to call the Activity call only once after the end of the cycle.

Can there be an opportunity to manually make a progress bar when the get() method is executed? What other options are there? Thank!

    3 answers 3

    Why do you need such a garden with AsyncTasks and cycles? Your way to not get what you want. Either you will have many AsyncTasks running, without waiting for the previous one to complete, or your UI will be blocked. If you so want to use AsyncTask, then carry out all the work in 1 AsyncTask without any cycles.

    Another option is to start the service, and after completing the work, send Broadcast, catch it in Activity1 and launch Activity2.

    Edit:

    Why not do something like this:

     private class MyAsyncTask extends AssyncTask<Void, Void, String> { protected Long doInBackground(URL... urls) { StringBuilder builder = new StringBuilder(); //пформируем результат while(true){ String string = getHtmString(); builder.append(string); } return builder.toString(); } protected void onPostExecute(String result) { //здесь обрабатываете результат } } 

    Edit2:

    Just like in the loop, create only one instance and transfer all the work to doInBackground() . You can also create a separate class in which all the work will take place, and which will have a public method that returns the result. And transfer all your logic to get the result there, in and doInBAckground() call only the method of this class. You should have something like this:

     private class MyAsyncTask extends AssyncTask<Void, Void, String> { protected Long doInBackground(URL... urls) { HtmlUtils htmlUtils = new HtmlUtils(); return htmlUtils.getResult(); } protected void onPostExecute(String result) { //здесь обрабатываете результат } } public class HtmlUtils(){ //some code public String getResult(){//some code} } 

    And in activation you call new MyAsyncTask().execute(null);

    • thanks for the answer. but I have a problem in that I get String in the form of HTML code from each completed async, resulting in a string from a previous finished async, and ultimately there should be one common String html that I want to show in Webview in another Activity - Mac
    • I think that it is possible to make a cycle not in the UI thread, but in the asynccussion itself and the intention, to cause it in the onpostexecute itself, but then the question is how to make the asynccusc in a separate class and call it in the main activation. Since I have a lot of code in the doinbackground. - Mac

    Good day!

    I solve a similar problem as follows:

    1. Create a procedure that will select the first element of the array and send it for processing or, in the case of array completion, perform some actions:
       public void OnStartOperation () {
           if ((array! = null) && (array.size> 0)) {
               String item = array.get (0);
               ... Pre-processing code ...
               new MyAsynctask (). execute ();
           } else {
               ... End code for loop processing ...
           }
       }
      
    2. Modify AsincTask as follows (only onPostExecute):
       @Override
           protected void onPostExecute (Void result) {
               super.onPostExecute (result);
               if (pDialog.isShowing ())
               pDialog.dismiss ();
      
               // Delete the spent record
               if ((array! = null) && (array.size ()> 0) {
                   array.remove (0);
               }
               // Start the next iteration
               OnStartOperation ();
           }
      

    Hope will help.

    • Thanks, not a bad option. but then the array is deleted and it cannot be reused. the fact is that this cycle (or OnStartOperation ()) is called by the button Onclick. That is, then everything will work but only once - Mac
    • In this case, simply duplicate the array at the touch of a button and send a duplicate for processing. - mg-demin

    Here either all the work that is executed in the cycle is immediately brought to AsinkTask, or if it is exactly necessary to create 100500 AsinkTasks and wait for their execution, then it is better to use Thread Executor
    Only then in the cycle it will be necessary to create not AsinkTaski but Runnables, which are sent to Executor for execution. The executor manages the execution of the work created, perhaps one by one, if it is necessary, it is possible in batches, there it is 5. And in the end, as all runables will work out - the transition to another activity.