在Android中下载文件时,ProgressBar不会更新

时间:2013-01-25 19:05:36

标签: android download progress-bar progressdialog

我几乎阅读了所有相似的主题,但我找不到解决方案。所以我决定问自己。

我想在操作过程中下载文件并显示进度对话框。该文件已成功下载。

第一个问题是进度条在下载操作期间不会更新。它只保留%0,下载完成后,对话框会按预期消失。

第二个问题是 - 我意外地注意到了这一点 - 当我的活动更新时(例如,当屏幕方向改变时),对话框消失但下载继续。

我希望有人可以提供帮助。

这是我的代码:

package com.mehmetakiftutuncu.downloadunzipshow;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLConnection;

import android.app.Activity;
import android.app.ProgressDialog;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class MainActivity extends Activity implements OnClickListener
{
    final String LOG_TAG = "DownloadUnzipShow";

    final String RELATIVE_PATH = "mehmetakiftutuncu";
    final String FILE_NAME = "...";
    final String FILE_URL = "...";
    final String FULL_PATH = Environment.getExternalStorageDirectory().getPath() + "/" + RELATIVE_PATH + "/";;

    Button buttonDownload, buttonUnzip, buttonShow;
    ProgressDialog progressDialog;

    public class MyFileDownloader extends AsyncTask<String, String, String>
    {
        boolean isSuccessful = true;

        InputStream inputStream;
        OutputStream outputStream;

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

            Log.d(LOG_TAG, "Downloading: " + FILE_URL + " to " + FULL_PATH + FILE_NAME);
        }

        @Override
        protected String doInBackground(String... params)
        {
            int count;

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

                connection.connect();

                int lengthOfFile = connection.getContentLength();

                File path = new File(FULL_PATH);
                if(!path.exists())
                {
                    path.mkdir();
                }

                inputStream = new BufferedInputStream(url.openStream());
                outputStream = new FileOutputStream(FULL_PATH + FILE_NAME);

                byte[] data = new byte[1024];

                long total = 0;
                int percentage = 0;

                while((count = inputStream.read(data)) != -1)
                {
                    total += count;

                    percentage = (int) ((total / lengthOfFile) * 100);

                    publishProgress(String.valueOf(percentage));

                    outputStream.write(data, 0, count);
                }

                outputStream.flush();
                outputStream.close();
                inputStream.close();
            }
            catch(Exception e)
            {
                isSuccessful = false;
                Log.e(LOG_TAG, "An error occured while downloading. Details: " + e.getMessage());
            }

            return null;
        }

        @Override
        protected void onProgressUpdate(String... values)
        {
            super.onProgressUpdate(values);

            progressDialog.setProgress(Integer.parseInt(values[0]));
        }

        @Override
        protected void onPostExecute(String result)
        {
            super.onPostExecute(result);

            if(isSuccessful)
            {
                Log.d(LOG_TAG, "File is successfully downloaded to: " + FULL_PATH + FILE_NAME);
            }

            progressDialog.dismiss();
        }
    }

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        buttonDownload = (Button) findViewById(R.id.button_download);

        buttonDownload.setOnClickListener(this);
    }

    private void prepareProgressDialog()
    {
        progressDialog = new ProgressDialog(this);
        progressDialog.setTitle(getString(R.string.dialog_title));
        progressDialog.setMessage(getString(R.string.dialog_message) + FILE_URL);
        progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
        progressDialog.setMax(100);
        progressDialog.setCancelable(false);
        progressDialog.show();
    }

    @Override
    public void onClick(View v)
    {
        switch(v.getId())
        {
            case R.id.button_download:
                new MyFileDownloader().execute(FILE_URL);
                break;
        }
    }
}

2 个答案:

答案 0 :(得分:3)

  

第一个问题是进度条在更新期间没有更新   下载操作。它只保留%0和下载时间   完成后,对话框会按预期消失。

这是因为行:

percentage = (int) ((total / lengthOfFile) * 100);

总是返回0,因为您正在进行整数java分区,其中total小于lengthOfFile。将total设为double值。也不要将百分比转换为String,将AsyncTask的第二个通用参数修改为Integer

  

第二个问题是 - 当我的活动时,我意外地注意到了这一点   得到更新(例如,当屏幕方向改变时)   对话框消失,但下载继续。

在配置更改(例如轮换)上,将重新创建Activity,从而在此过程中终止对话框。如果要重新显示对话框,则需要将AsyncTask保留在配置更改中,方法是将其传递给onRetainNonConfigurationInstance()的{​​{1}}方法(或者您可以使用片段) 。在Activity方法中,使用onCreate查看是否保留了任务并仍在运行并重新显示对话框。另外,你真的不应该让getLastNonConfigurationInstance成为AsyncTask中的内部类,因为你会将它与活动联系起来。

答案 1 :(得分:0)

对话框消失了 - 您是在捕获方向配置更改,还是让Android执行此操作?如果您让Android执行此操作,它将终止您的活动并重新创建它,这将破坏您的对话框。异步任务不会被杀死,因为异步任务由系统拥有。要解决此问题,请将android:configChange =“orientation”添加到活动的清单中。一般的经验法则是,如果您希望通过旋转保持对话框,则需要这样做。