1

У меня многократная работа asynctask в цикле for внутри моего заставки. Я хочу, чтобы приложение прекратило выполнение до тех пор, пока все asynctasks не будут завершены. И я хотел бы обновить поток пользовательского интерфейса с общим количеством задач async и задачи. Если у вас 3 задачи и 1 завершен, я бы хотел отобразить 1/3 завершено. Это код цикла: -Как остановить выполнение до тех пор, пока все задачи async не закончат выполнение в android?

String[] images = Parse_imgJSON.image; 
     for (int i = 0; i < images.length; i++) { 
      Log.d("Image ", images[i]); 
      download_img(images[i]); 
     } 

Код для download_img(): -

public void download_img(String img_url) { 
    String fileName = img_url.substring(img_url.lastIndexOf('/') + 1, img_url.length()); 
    File file = new File("/storage/emulated/0/rready_images/" + fileName); 

    if (file.exists() && !file.isDirectory()) { 
     Log.d("Image exists", fileName); 

    } else { 
     if (fileName.contains(".jpg") || fileName.contains(".gif") || fileName.contains(".png")) { 
      new DownloadImagesAsync().execute(img_url); 
     } else { 
      Log.d("IMAGE DOWNLOAD ", "FAILED FOR " + fileName); 

     } 

    } 
} 

Фактический код Асинхронный Задача для скачивания файла: -

 class DownloadImagesAsync extends AsyncTask<String, String, String> { 

     Boolean isSDPresent = android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED); 

     private String resp; 
     int lengthOfFile; 

     @Override 
     protected String doInBackground(String... params) { 


      int count; 

      try { 
       URL url = new URL(params[0]); 
       URLConnection connection = url.openConnection(); 
       connection.connect(); 

       lengthOfFile = connection.getContentLength(); 
       Log.d("ANDRO_ASYNC", "LENGTH OF FILE : " + lengthOfFile); 

       String fileName = params[0].substring(params[0].lastIndexOf('/') + 1, params[0].length()); 
       Log.d("FILENAME", fileName); 
       resp = fileName; 

       if (isSDPresent) { 

        InputStream inputStream = new BufferedInputStream(url.openStream()); 
        OutputStream outputStream = new FileOutputStream("sdcard/rreadyreckoner_images/" + fileName); 
        byte data[] = new byte[1024]; 
        long total = 0; 
        while ((count = inputStream.read(data)) != -1) { 
         total += count; 
         outputStream.write(data, 0, count); 
        } 

        outputStream.flush(); 
        outputStream.close(); 
        inputStream.close(); 
       } else { 
        InputStream inputStream = new BufferedInputStream(url.openStream()); 
        OutputStream outputStream = new FileOutputStream(getFilesDir() + "/rreadyreckoner_images/" + fileName); 
        byte data[] = new byte[1024]; 
        long total = 0; 
        while ((count = inputStream.read(data)) != -1) { 
         total += count; 
         outputStream.write(data, 0, count); 
        } 

        outputStream.flush(); 
        outputStream.close(); 
        inputStream.close(); 

       } 


      } catch (Exception e) { 
       e.printStackTrace(); 
      } 
      return params[0]; 
     } 

     @Override 
     protected void onPostExecute(String filename) { 
      Log.d("PARAM", filename + " Downloaded "); 

      String fname = filename.substring(filename.lastIndexOf('/') + 1, filename.length()); 

      Log.d("LENGTH OF FILE : ", String.valueOf(lengthOfFile)); 

      if (isSDPresent) { 

       File f = new File("/storage/emulated/0/rreadyreckoner_images/" + fname); 
       if (f.length() < lengthOfFile) { 
        if (f.delete()) { 

         // Toast.makeText(RReadySplash.this, "Download was interrupted please try again!", Toast.LENGTH_SHORT).show(); 
         Log.d("Del", "File deleted"); 
        } else { 

         Log.d("NOTDel", "File not deleted"); 
        } 
       } else { 

        // dbHandler.updateDownloadStatus(image_id, "YES"); 

       } 

      } else { 

       File f = new File("/storage/emulated/0/rreadyreckoner_images/" + fname); 
       if (f.length() < lengthOfFile) { 
        if (f.delete()) { 

         Log.d("Del", "File deleted"); 
        } else { 

         Log.d("NOTDel", "File not deleted"); 
        } 
       } else { 

//     dbHandler.updateDownloadStatus(image_id, "YES"); 


       } 


      } 


     } 

     @Override 
     protected void onPreExecute() { 
      super.onPreExecute(); 

     } 

     @Override 
     protected void onProgressUpdate(String... values) { 
      Log.d("ANDRO_ASYNC", values[0]); 

     } 
    } 

Любая помощь или предложение приветствуется. Спасибо.

+0

Вы должны использовать onPreExecute() в каждой задаче, чтобы приостановить то, что вам нужно сделать паузу, а затем в onPostExecute() использовать статическую переменную для увеличения количества выполненных задач (int i); e.g -> tv.setText (++ i + "/ 3"); – Lazai

+0

Если вы хотите проверить выполнение, сделайте это в 'onPostExecute', а не сделайте это в' onPreExecute'. –

ответ

1

Существует много методов.

Например, вы можете использовать обратные вызовы интерфейса.

Создание интерфейса:

public interface MyCallback { 
    public void readycallback(int index_thread); 
} 

изменения класса:

class DownloadImagesAsync extends AsyncTask<String, String, String> { 
private int id = 0; 
private MyCallback callback; 
      Boolean isSDPresent = android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED); 

      private String resp; 
      int lengthOfFile; 
    public DownloadImagesAsync(int id, MyCallback callback) { 
this.id = id; 
this.callback = callback; 
} 
      @Override 
      protected String doInBackground(String... params) { 


       int count; 

       try { 
        URL url = new URL(params[0]); 
        URLConnection connection = url.openConnection(); 
        connection.connect(); 

        lengthOfFile = connection.getContentLength(); 
        Log.d("ANDRO_ASYNC", "LENGTH OF FILE : " + lengthOfFile); 

        String fileName = params[0].substring(params[0].lastIndexOf('/') + 1, params[0].length()); 
        Log.d("FILENAME", fileName); 
        resp = fileName; 

        if (isSDPresent) { 

         InputStream inputStream = new BufferedInputStream(url.openStream()); 
         OutputStream outputStream = new FileOutputStream("sdcard/rreadyreckoner_images/" + fileName); 
         byte data[] = new byte[1024]; 
         long total = 0; 
         while ((count = inputStream.read(data)) != -1) { 
          total += count; 
          outputStream.write(data, 0, count); 
         } 

         outputStream.flush(); 
         outputStream.close(); 
         inputStream.close(); 
        } else { 
         InputStream inputStream = new BufferedInputStream(url.openStream()); 
         OutputStream outputStream = new FileOutputStream(getFilesDir() + "/rreadyreckoner_images/" + fileName); 
         byte data[] = new byte[1024]; 
         long total = 0; 
         while ((count = inputStream.read(data)) != -1) { 
          total += count; 
          outputStream.write(data, 0, count); 
         } 

         outputStream.flush(); 
         outputStream.close(); 
         inputStream.close(); 

        } 


       } catch (Exception e) { 
        e.printStackTrace(); 
       } 
       return params[0]; 
      } 

      @Override 
      protected void onPostExecute(String filename) { 
       Log.d("PARAM", filename + " Downloaded "); 
    if (callback != null) { 
callback.readycallback(myid); 
} 
       String fname = filename.substring(filename.lastIndexOf('/') + 1, filename.length()); 

       Log.d("LENGTH OF FILE : ", String.valueOf(lengthOfFile)); 

       if (isSDPresent) { 

        File f = new File("/storage/emulated/0/rreadyreckoner_images/" + fname); 
        if (f.length() < lengthOfFile) { 
         if (f.delete()) { 

          // Toast.makeText(RReadySplash.this, "Download was interrupted please try again!", Toast.LENGTH_SHORT).show(); 
          Log.d("Del", "File deleted"); 
         } else { 

          Log.d("NOTDel", "File not deleted"); 
         } 
        } else { 

         // dbHandler.updateDownloadStatus(image_id, "YES"); 

        } 

       } else { 

        File f = new File("/storage/emulated/0/rreadyreckoner_images/" + fname); 
        if (f.length() < lengthOfFile) { 
         if (f.delete()) { 

          Log.d("Del", "File deleted"); 
         } else { 

          Log.d("NOTDel", "File not deleted"); 
         } 
        } else { 

    //     dbHandler.updateDownloadStatus(image_id, "YES"); 


        } 


       } 


      } 

      @Override 
      protected void onPreExecute() { 
       super.onPreExecute(); 

      } 

      @Override 
      protected void onProgressUpdate(String... values) { 
       Log.d("ANDRO_ASYNC", values[0]); 

      } 
     } 

использовать этот класс изменить основную функцию

String[] images = Parse_imgJSON.image; 
     for (int i = 0; i < images.length; i++) { 
      Log.d("Image ", images[i]); 
      download_img(images[i], i); 
     } 




public void download_img(String img_url, int i) { 
     String fileName = img_url.substring(img_url.lastIndexOf('/') + 1, img_url.length()); 
     File file = new File("/storage/emulated/0/rready_images/" + fileName); 

     if (file.exists() && !file.isDirectory()) { 
      Log.d("Image exists", fileName); 



      } else { 
       if (fileName.contains(".jpg") || fileName.contains(".gif") || fileName.contains(".png")) { 
        new DownloadImagesAsync(i, new MyCallback() { 
@Override 
    public void readycallback(int index_thread) { 

    //this is your ready callback 

    } 
    }).execute(img_url); 
       } else { 
        Log.d("IMAGE DOWNLOAD ", "FAILED FOR " + fileName); 

       } 

      } 
    } 

Не забудьте проверить, используете ли вы главный интерфейс резьба:

если вам нужно, вы можете обернуть обновления этой функции:

@Override 
    public void readycallback(int index_thread) { 

    //this is your ready callback 
    runOnUiThread(new Runnable() { 
       @Override 
       public void run() { 
        //this is your ready callback in main UI 
//I do not remember if onPostExecute is in main UI thread 
       } 
      }); 
    } 
+0

Можете ли вы дать пример кода, это было бы очень полезно. Спасибо. – AndroidNewBee

+0

Да. Подожди немного. – Vyacheslav

+0

@AndroidNewBee, вот и все. check – Vyacheslav

3

Весь смысл использования задачи async состоит в том, чтобы не блокировать основной поток. Попытка заблокировать все операции до тех пор, пока файлы не будут загружены в async-задачу, возможно, не подходит, и определенно не рекомендуется. Вместо этого я предлагаю вам загрузить нужные файлы и сохранить их с помощью фоновой службы, которая запускается при первой установке пользователем приложения, так что вам просто нужно прочитать при запуске. И если вам удастся остановить всю работу до завершения загрузки, вы получите сообщение ANR.

Итак, что вы можете сделать в этой ситуации, используйте фрагмент и AsyncTaskLoader или фон service, который передает намерение после завершения загрузки вместо задачи Async, поскольку задача Async рекомендуется только для коротких операций. Слушайте эту трансляцию, зарегистрировав приемник и обновив свой интерфейс после получения результата от загрузчика или службы.

1

Я использую ProgressBar, чтобы отобразить обновления в качестве примера. Вы можете, конечно, выбрать любой вид, который вам нравится. В download_img() я увеличиваю значение так, чтобы оно показывало 1/3 вместо 0/3.

Кроме того, я предполагаю, что все эти методы и AsyncTask находятся в одном Java-файле.

ProgressBar mProgress = (ProgressBar) findViewById(R.id.progress_bar);    <------------Here 

probressbar.setMax(images.length)    <---------------Here 

      for (int i = 0; i < images.length; i++) { 
         Log.d("Image ", images[i]); 
         download_img(images[i], i); 
      } 

download_img()

public void download_img(String img_url, int i) {   <---------------Here 
String fileName = img_url.substring(img_url.lastIndexOf('/') + 1, img_url.length()); 
File file = new File("/storage/emulated/0/rready_images/" + fileName); 

if (file.exists() && !file.isDirectory()) { 
    Log.d("Image exists", fileName); 

} else { 
    if (fileName.contains(".jpg") || fileName.contains(".gif") || fileName.contains(".png")) { 
     new DownloadImagesAsync().execute(img_url, ++i);   <------------------Here 
    } else { 
     Log.d("IMAGE DOWNLOAD ", "FAILED FOR " + fileName); 

    } 

} 
} 

AsyncTask

class DownloadImagesAsync extends AsyncTask<String, String, String> { 

    Boolean isSDPresent = android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED); 

    private String resp; 
    int lengthOfFile, progressStatus;     <------------Here 

    @Override 
    protected String doInBackground(String... params) { 


     int count; 

     try { 
      progressStatus=Integer.parseInt(params[1]);    <-----------Here 
      URL url = new URL(params[0]); 
      URLConnection connection = url.openConnection(); 
      connection.connect(); 

      lengthOfFile = connection.getContentLength(); 
      Log.d("ANDRO_ASYNC", "LENGTH OF FILE : " + lengthOfFile); 

      String fileName = params[0].substring(params[0].lastIndexOf('/') + 1, params[0].length()); 
      Log.d("FILENAME", fileName); 
      resp = fileName; 

      if (isSDPresent) { 

       InputStream inputStream = new BufferedInputStream(url.openStream()); 
       OutputStream outputStream = new FileOutputStream("sdcard/rreadyreckoner_images/" + fileName); 
       byte data[] = new byte[1024]; 
       long total = 0; 
       while ((count = inputStream.read(data)) != -1) { 
        total += count; 
        outputStream.write(data, 0, count); 
       } 

       outputStream.flush(); 
       outputStream.close(); 
       inputStream.close(); 
      } else { 
       InputStream inputStream = new BufferedInputStream(url.openStream()); 
       OutputStream outputStream = new FileOutputStream(getFilesDir() + "/rreadyreckoner_images/" + fileName); 
       byte data[] = new byte[1024]; 
       long total = 0; 
       while ((count = inputStream.read(data)) != -1) { 
        total += count; 
        outputStream.write(data, 0, count); 
       } 

       outputStream.flush(); 
       outputStream.close(); 
       inputStream.close(); 

      } 


     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
     return params[0]; 
    } 

    @Override 
    protected void onPostExecute(String filename) { 
     Log.d("PARAM", filename + " Downloaded "); 
     mProgress.setProgress(mProgressStatus);   <----------------Here 

     String fname = filename.substring(filename.lastIndexOf('/') + 1, filename.length()); 

     Log.d("LENGTH OF FILE : ", String.valueOf(lengthOfFile)); 

     if (isSDPresent) { 

      File f = new File("/storage/emulated/0/rreadyreckoner_images/" + fname); 
      if (f.length() < lengthOfFile) { 
       if (f.delete()) { 

        // Toast.makeText(RReadySplash.this, "Download was interrupted please try again!", Toast.LENGTH_SHORT).show(); 
        Log.d("Del", "File deleted"); 
       } else { 

        Log.d("NOTDel", "File not deleted"); 
       } 
      } else { 

         // dbHandler.updateDownloadStatus(image_id, "YES"); 

      } 

     } else { 

      File f = new File("/storage/emulated/0/rreadyreckoner_images/" + fname); 
      if (f.length() < lengthOfFile) { 
       if (f.delete()) { 

        Log.d("Del", "File deleted"); 
       } else { 

        Log.d("NOTDel", "File not deleted"); 
       } 
      } else { 

        //dbHandler.updateDownloadStatus(image_id, "YES"); 


      } 


     } 


    } 

    @Override 
    protected void onPreExecute() { 
     super.onPreExecute(); 

    } 

    @Override 
    protected void onProgressUpdate(String... values) { 
     Log.d("ANDRO_ASYNC", values[0]); 

    } 
} 
Смежные вопросы