AsynTaskとProgressDialogを実装するときに私が首を絞めてしまいました。小さなファイルをダウンロードすると、すべて正常に動作し、進行状況は0%から100%に更新されます。しかし、大きなファイルをダウンロードすると、ProgressDialogの数字は6または7%になり、もう更新されません。しかし2,3分後、私はasyntaskタスクがダウンロードプロセスを終了するというメッセージを受け取ります。大きなファイルをダウンロードするときにAsynTaskが実行中にProgrressDialogがフリーズします
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のメッセージがコンソールに表示されます)。
ここに私のコードです
誰かに何か問題がありますか?
編集
私はダルコの提案として1メガバイトにバッファサイズを変更しましたが、それはまだ動作しません。私は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分後に表示されました。あなたが見ることができるように、ファイルは完全にダウンロードされていません。
私は日食のデバッグツールで私のアプリをデバッグ、私はあなたがあまりにも頻繁に、それは時間の更新とそのブロックに表示カント、それを更新している
OSNetworkSystem.receiveStreamImpl(FileDescriptor, byte[], int, int, int) line: not available [native method]
私は1024バイトのバッファを使用することも非常に非効率的になることに同意します。 'lenghthOfFile'を使用して、ダウンロードするファイルのサイズに基づいて割り当てることを提案し、合計の20%または10%をバッファに割り当てることをお勧めします。これにより進捗状況の更新も遅くなります。 – Squonk
あるいは、あなたが知っているように、「パーセント」(新しい変数)が1に増えるたびにアップデートを公開するだけです。 – dmon
最初はパーセンテージについてです。つまり、新しいパーセンテージを計算し、比較し、保存する必要があります。進行状況の更新も非常に非効率的です。とバッファサイズについて私の意見は、あなたが固定サイズではなく、代わりに大きなサイズのファイルを考えているので、dinamicallyファイルサイズに調整する必要があることです(100 mbのようなメモリクラッシュ、 mbは10MBのバッファですが、メモリ不足の可能性もあります。私の経験では、0.5MBから1MBまではバッファサイズが大きいと言われています – DArkO