I'm downloading files by using android download manager. Files are multiple, and I'm showing their progress inside of listview. my code is working fine but when my downloads gets more than 4 or 5 the listview gets very slow, infact the whole app gets slow. In a few moment it gets stuck and I've to forcibly close because phone also gets hanged. here is my code to update listview.
private class UpdaterAsyncTask extends AsyncTask<Void, Void, Void> {
boolean isRunning = true;
boolean progressBusy = false;
public void stop() {
isRunning = false;
}
@Override
protected Void doInBackground(Void... params) {
while (isRunning) {
if(progressBusy==true){
}
else{
progressBusy = true;
publishProgress();
}
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return null;
}
@Override
protected void onProgressUpdate(Void... params) {
super.onProgressUpdate();
try {
progressBusy = false;
if (mScrollState == OnScrollListener.SCROLL_STATE_IDLE) {
int start = Lv_DownloadItems.getFirstVisiblePosition();
for (int i = start, j = Lv_DownloadItems
.getLastVisiblePosition(); i <= j; i++) {
View view = Lv_DownloadItems.getChildAt(i - start);
DownloadManager.Query q = new DownloadManager.Query();
q.setFilterById(Long.parseLong(progress_ids
.get(i)));
final Cursor cursor = downloadManager.query(q);
cursor.moveToFirst();
long bytes_downloaded = cursor
.getInt(cursor
.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR));
int bytes_total = cursor
.getInt(cursor
.getColumnIndex(DownloadManager.COLUMN_TOTAL_SIZE_BYTES));
int len1 = (int)(bytes_downloaded * 100 / bytes_total);
int columnIndex = cursor
.getColumnIndex(DownloadManager.COLUMN_STATUS);
ProgressBar progress = (ProgressBar) view
.findViewById(R.id.progressBar1);
progress.setProgress(len1);
TextView txtStatus = (TextView) view
.findViewById(R.id.percentage);
// txtStatus.setPadding(10, 0, 0, 0);
txtStatus.setText(String.valueOf(len1) + "%");
cursor.close();
}
}
} catch (Exception ec) {
ec.printStackTrace();
}
}
}
I call this async task at onResume
UpdaterAsyncTask mUpdater = new UpdaterAsyncTask();
mUpdater.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,
(Void) null);
I'm totally gets stuck and don't know where i'm wrong, please help me. Any help would be much appreciated. thank you :)
Thread.sleep(16);
. 16 ms ? That is short. onProgressUpdate will take much more time than that. But what is more: if you call publishProgress() so often they will all stack up as onProgressUpdate will only later get called when the OS has time to do that on the UI thread. With a little adaptation you can prevent an to early calling of publishProgress(). Add to the asynctask avolatile boolean progressBusy = false;
Set it to true before calling publishProgress(). Set it to false again in onProgressUpdate. In doInBackground do not call publishProgress() if progressBusy is true.