我几乎阅读了所有相似的主题,但我找不到解决方案。所以我决定问自己。
我想在操作过程中下载文件并显示进度对话框。该文件已成功下载。
第一个问题是进度条在下载操作期间不会更新。它只保留%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;
}
}
}
答案 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”添加到活动的清单中。一般的经验法则是,如果您希望通过旋转保持对话框,则需要这样做。