【问题标题】:Not able to publish progress from async task do in background's while loop - Android无法在后台的while循环中发布异步任务的进度 - Android
【发布时间】:2016-03-12 01:57:54
【问题描述】:

我想从 doInBackground 更新对话框的下载进度。
我正在打印日志以及发布进度。
他们都没有工作。

它在最后更新对话框并在最后一次打印所有日志值

private class DownloadEReport extends AsyncTask<String, Void, Void> {
    int progress = 0;

    protected void onPreExecute() {
        mProgressDialog = new ProgressDialog(EReport.this);
        mProgressDialog.setTitle("Downloads");
        mProgressDialog.setMessage("Downloading, Please Wait!");
        mProgressDialog.setIndeterminate(false);
        mProgressDialog.setMax(100);
        mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
        mProgressDialog.setCancelable(false);
        mProgressDialog.show();
    }

    @Override
    protected void onProgressUpdate(Void... values) {
        super.onProgressUpdate(values);
        mProgressDialog.setProgress(progress);
    }



    @Override
    protected Void doInBackground(String... strings) {

        String mUrl = strings[0];
        String json = "";
        int count;
        try {
            URL url = new URL(mUrl);
            URLConnection conection = url.openConnection();
            conection.connect();
            // getting file length
            int lenghtOfFile = conection.getContentLength();

            // input stream to read file - with 8k buffer
            InputStream input = new BufferedInputStream(url.openStream(), 8192);

            // Output stream to write file
            OutputStream output = new FileOutputStream("/sdcard/downloadedfile.txt");

            byte data[] = new byte[1024];
            long total = 0;
            while ((count = input.read(data)) != -1) {
                total += count;
                // writing data to file
                output.write(data, 0, count);

                // publishing the progress....
                // After this onProgressUpdate will be called
                Log.e("JSON Download Progress", "" + (int) ((total * 100) / lenghtOfFile));
                progress = (int) (total * 100 / lenghtOfFile);
                publishProgress();
            }

            // flushing output
            output.flush();
            // closing streams
            output.close();
            input.close();

        } catch (Exception e) {
            Log.e("Error: ", e.getMessage());
        }

        return null;
    }

    @Override
    protected void onPostExecute(Void aVoid) {
        super.onPostExecute(aVoid);
        mProgressDialog.dismiss();
    }
}

【问题讨论】:

    标签: java android android-layout android-asynctask background


    【解决方案1】:

    从 onProgressUpdate 中移除 super 然后尝试

    @Override
    protected void onProgressUpdate(Void... values) {
        //super.onProgressUpdate(values);
        mProgressDialog.setProgress(progress);
    }
    

    如果它不起作用,则在循环中添加一个 sleep 语句,以便此循环释放处理器并给时间发布进度

    try {
        Thread.sleep(200);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    

    【讨论】:

    • 我遇到了类似的问题,即我的进度条没有在屏幕上更新,即使一切设置正确。事实证明,在阅读了您的答案并考虑了我的设置之后,问题出在我的 Thread.Sleep 上。我一直在 while 循环中(在 doInBackground 中)执行 Thread.Sleep(100) 并在其中调用 publishUpdate。直到我将睡眠时间增加到 1000 时它才开始工作。我能够将其缩小到大约 250 ......但是,在其他设备上它可能会有所不同。谁能解释一下?
    • 我认为您正在更新很多用户界面元素,这就是为什么处理器需要 1 秒来更新 UI,我说的对吗?
    • 我实际上只更新了一个 UI 元素 - ProgressBar。我实际上应该用我的问题创建一个问题。谢谢
    【解决方案2】:

    对该行为的一种可能解释是从远程输入流中读取并将其写入输出缓冲区非常快。 我尝试了相同的代码,但只运行了 10 次循环。

    int total = 0;
    while(total <= 100){
        progress = total;
        total += 10;
        publishProgress();
    }
    

    即使我一开始也看不到进度对话框,所以将 Thread.sleep() 放入循环中,进度对话框就可以正常工作了。

    int total = 0;
            while(total <= 100){
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                progress = total;
                total += 10;
                publishProgress();
            }
    

    尝试记录您写入输出缓冲区的时间 (System.currentTimeMillis())。

    希望对您有所帮助。

    【讨论】:

    • 这会非常昂贵,因为这个循环将被调用数百次,并且 thread.sleep 将导致 2 分钟延迟:/
    猜你喜欢
    • 2018-12-26
    • 2020-05-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-30
    • 2020-12-03
    • 2020-09-04
    • 1970-01-01
    相关资源
    最近更新 更多