【发布时间】:2011-06-21 19:26:25
【问题描述】:
在实现 AsynTask 和 ProgressDialog 时,我有一种扼杀行为。当我下载小文件时,一切正常,进度状态从 0% 更新到 100%。但是当我下载更大的文件时,ProgressDialog 上的数字会运行到 6% 或 7%,然后就不再更新了。但是 2,3 分钟后,我收到一条消息,说 asyntask 任务完成了下载过程。
public class DownloadHelper extends AsyncTask<String, Integer, Long> implements DialogInterface.OnDismissListener{
private volatile boolean running = true;
private PhonegapActivity _ctx = null;
private ProgressDialog _progressDialog = null;
private String _title = null;
private File _root = null;
private File _destination = null;
private DatabaseHelper _dbHelper = null;
private Cursor _cursorMedia = null;
public DownloadHelper(String title, File root, File destination, DatabaseHelper dbHelper, PhonegapActivity ctx){
_title = title;
_ctx = ctx;
_root = root;
_destination = destination;
_dbHelper = dbHelper;
}
@Override
protected void onPreExecute() {
if (_progressDialog != null)
{
_progressDialog.dismiss();
_progressDialog = null;
}
_progressDialog = new ProgressDialog(_ctx);
_progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
_progressDialog.setTitle("Downloading");
_progressDialog.setMessage(_title);
_progressDialog.setCancelable(true);
_progressDialog.setMax(100);
_progressDialog.setProgress(0);
/*_progressDialog.setOnCancelListener(
new DialogInterface.OnCancelListener() {
public void onCancel(DialogInterface dialog) {
_progressDialog = null;
running = false;
}
});
_progressDialog.setOnDismissListener(
new DialogInterface.OnDismissListener() {
public void onDismiss(DialogInterface dialog) {
Log.d("DownloadHelper", "canceled inside listener");
_progressDialog = null;
running = false;
}
}
);*/
_progressDialog.show();
running = true;
}
@Override
protected Long doInBackground(String... sUrl) {
try {
Log.d("DownloadHelper", "Start download from url " + sUrl[0]);
long total = 0;
total = _download(sUrl[0], _destination);
return total;
} catch (Exception ex2) {
ex2.printStackTrace();
Log.d("DownloadHelper", "Failed to download test file from " + sUrl[0] + " to " + _destination.getAbsolutePath().toString());
_closeProgressDialog();
}
return null;
}
protected void onCancelled(Long result) {
Log.d("DownloadHelper", "CANCELLED result = " + result);
_closeProgressDialog();
}
protected void onProgressUpdate(Integer... progress) {
if (_progressDialog != null && running)
{
Log.d("DownloadHelper", "UPDATED progess = " + progress[0]);
_progressDialog.setProgress(progress[0]);
}
else //cancel the task
{
Log.d("DownloadHelper", "onProgressUpdate cancelled");
cancel(true);
}
}
protected void onPostExecute(Long result) {
Log.d("DownloadHelper", "FINISHED result = " + result);
// Close the ProgressDialog
_closeProgressDialog();
running = false;
if (result != null) //OK
{
_showAlertDialog("Test has been downloaded successfully.", "Message", "OK");
}
else // error
{
_showAlertDialog("Can not download the test. Please try again later.", "Error", "OK");
}
}
@Override
protected void onCancelled() {
running = false;
}
public void onDismiss(DialogInterface dialog) {
Log.d("DownloadHelper", "Cancelled");
this.cancel(true);
}
protected void _closeProgressDialog(){
if (_progressDialog != null)
{
_progressDialog.dismiss();
_progressDialog = null;
}
}
protected void _showAlertDialog(final String message, final String title, final String buttonLabel){
AlertDialog.Builder dlg = new AlertDialog.Builder(_ctx);
dlg.setMessage(message);
dlg.setTitle(title);
dlg.setCancelable(false);
dlg.setPositiveButton(buttonLabel,
new AlertDialog.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
dlg.create();
dlg.show();
}
protected Cursor _checkMedia() {
_dbHelper.openDatabase(_destination.getAbsolutePath());
Log.d("DownloadHelper", "Database is opened");
String[] columns = {"type, size, location, location_id, url"};
Cursor cursor = _dbHelper.get("media", columns);
_dbHelper.closeDatabase();
_dbHelper.close();
_dbHelper = null;
return cursor;
}
protected long _download(String sUrl, File destination) throws IOException {
URL url = new URL(sUrl);
URLConnection conexion = url.openConnection();
conexion.connect();
// this will be useful so that you can show a tipical 0-100% progress bar
int lenghthOfFile = conexion.getContentLength();
Log.d("DownloadHelper", "length of File = " + lenghthOfFile);
// downlod the file
InputStream input = new BufferedInputStream(url.openStream());
OutputStream output = new FileOutputStream(destination);
byte data[] = new byte[1024];
long total = 0;
int count;
// Reset the progress
_progressDialog.setProgress(0);
// Start downloading main test file
while ((count = input.read(data)) != -1 && running) {
total += count;
Log.d("DownloadHelper", "total = " + total);
// publishing the progress....
this.publishProgress((int)(total*100/lenghthOfFile));
output.write(data, 0, count);
}
if (running == false)
{
this.cancel(true);
}
output.flush();
output.close();
input.close();
return total;
}
}
我还在 onProgressUpdate() 中添加了一条 Log.d 消息,调试消息显示直到进度达到 6% 或 7%,然后控制台中不再出现任何内容(但该应用程序仍然有效,因为我没有收到任何错误消息和Gabrage Collector的消息仍然显示在控制台中)。
这是我的代码
有人有问题吗?
已编辑
根据 DArkO 的建议,我将缓冲区大小更改为 1MB,但它仍然不起作用。我认为我的 while 循环有问题。我在我的 while 循环中使用 log.d 并在控制台中有一些这样的:
D/DownloadHelper( 1666): length = **3763782**; total = 77356; percent = 2; save_percent = 0
D/DownloadHelper( 1666): UPDATED progess = 2
D/DownloadHelper( 1666): length = 3763782; total = 230320; percent = 6; save_percent = 0
D/DownloadHelper( 1666): UPDATED progess = 6
D/dalvikvm( 1666): GC freed 10241 objects / 1087168 bytes in 88ms
*D/DownloadHelper( 1666): FINISHED result = **230320***
“FINISHED 消息”来自 onPostExecute()。此消息在进度对话框停止后 1.2 分钟后出现。如您所见,该文件未完全下载。
我用eclipse的调试工具调试我的应用程序,我可以看到asynctask线程在这个函数处挂起
OSNetworkSystem.receiveStreamImpl(FileDescriptor, byte[], int, int, int) line: not available [native method]
【问题讨论】:
标签: android cordova android-asynctask freeze progressdialog