0

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

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

第一个问题是下载操作过程中进度条没有更新。它只是保持 %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;
        }
    }
}
4

2 回答 2

3

第一个问题是下载操作过程中进度条没有更新。它只是保持 %0 并且下载完成后,对话框会按预期消失。

发生这种情况是因为该行:

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

总是返回0,因为你正在做一个total小于lengthOfFile. 创造total价值double。也不要将百分比转换为,String将 的第二个通用参数修改为。AsyncTaskInteger

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

在配置更改(例如轮换)时,Activity将重新创建在此过程中杀死您的对话框。如果您想重新显示对话框,您需要AsyncTask通过将配置更改传递给(或者您可以使用片段)的onRetainNonConfigurationInstance()方法来保持配置更改。ActivityonCreate方法中用于getLastNonConfigurationInstance查看您是否保留了任务并仍在运行并重新显示对话框。此外,您真的不应该在中AsyncTask创建内部类,Activity因为您会将其与活动联系起来。

于 2013-01-25T19:37:02.190 回答
0

对话框消失了——你是在捕捉方向配置的变化,还是让 Android 来做?如果您让 Android 执行此操作,它将终止您的活动并重新创建它,这将破坏您的对话框。异步任务不会被杀死,因为异步任务归系统所有。要解决这个问题,请将 android:configChange="orientation" 添加到活动的清单中。一般的经验法则是,如果您想让对话在轮换中持续存在,您需要这样做。

于 2013-01-25T19:13:45.940 回答