【问题标题】:How to stop execution till all the async tasks finish execution in android?如何停止执行,直到所有异步任务在android中完成执行?
【发布时间】:2016-09-02 09:13:00
【问题描述】:

我有多个异步任务在我的初始屏幕内的 for 循环中运行。我希望应用程序停止执行,直到所有异步任务完成。我想用异步任务和任务完成的总数更新 UI 线程。就像有 3 个任务和 1 个完成我想显示 1 /3 完成。 这是循环的代码:-

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

        }
    }

感谢任何帮助或建议。谢谢。

【问题讨论】:

  • 您应该在每个任务中使用 onPreExecute() 来暂停您需要暂停的内容,然后在 onPostExecute() 中使用静态变量来增加已完成任务的数量(int i);例如 -> tv.setText(++i + "/3");
  • 如果您想检查是否完成,请在 onPostExecute 中进行,而不是在 onPreExecute 中进行。

标签: java android multithreading asynchronous android-asynctask


【解决方案1】:

使用异步任务的重点是不阻塞主线程。在异步任务中下载文件之前尝试阻止所有操作可能不是可行的方法,并且绝对不推荐。相反,我建议您下载所需的文件并使用在用户第一次安装应用程序时运行的后台服务来存储它们,这样您只需在启动时阅读。如果您在下载完成之前设法停止所有工作,您将收到一条 ANR 消息。

那么在这种情况下你可以做什么,使用片段和AsyncTaskLoader 或背景service 在下载完成后广播意图,代替异步任务,因为异步任务仅推荐用于短操作。通过注册一个接收器来监听这个广播,并在接收到来自加载器或服务的结果后相应地更新你的 UI。

【讨论】:

    【解决方案2】:

    有很多方法。

    例如,您可以使用接口回调。

    创建接口:

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

    不要忘记检查你是否使用主 UI 线程:

    如果你需要,你可以通过这个函数来包装更新:

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

    【讨论】:

    • 您能否提供一个示例代码,这将非常有帮助。谢谢。
    • @AndroidNewBee ,就是这样。检查
    【解决方案3】:

    我以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);
    
        }
    
    }
    }
    

    异步任务

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-12-20
      • 1970-01-01
      • 2014-08-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多