Better handling of cancelling of downloads.
One thing that still annoys me is that indeterminate progress dialog still shows "0/100" due to the number formatter being used to display the values in the TextView. Solution (from http://stackoverflow.com/a/6784180) is to either make a custom dialog, or at the very least, in API 11 or higher we can set the number formatter to display nothing. Don't show the full download path of repo. The full path includes the path to the index.jar, as well as ?clientVersion=*. This is undesirable, the main purpose of even showing where we are downloading from is to differentiate between multiple repos being updated at once.
This commit is contained in:
parent
3ed2cde207
commit
11ddf0478c
@ -1073,11 +1073,16 @@ public class AppDetails extends ListActivity implements ProgressListener {
|
||||
pd.setMessage(getString(R.string.download_server) + ":\n " + file);
|
||||
pd.setCancelable(true);
|
||||
pd.setCanceledOnTouchOutside(false);
|
||||
pd.setIndeterminate(true); // This will get overridden on the first progress event we receive.
|
||||
|
||||
// The indeterminate-ness will get overridden on the first progress event we receive.
|
||||
pd.setIndeterminate(true);
|
||||
|
||||
pd.setOnCancelListener(new DialogInterface.OnCancelListener() {
|
||||
@Override
|
||||
public void onCancel(DialogInterface dialog) {
|
||||
downloadHandler.cancel();
|
||||
progressDialog = null;
|
||||
Toast.makeText(AppDetails.this, getString(R.string.download_cancelled), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
});
|
||||
pd.setButton(DialogInterface.BUTTON_NEUTRAL,
|
||||
@ -1118,9 +1123,6 @@ public class AppDetails extends ListActivity implements ProgressListener {
|
||||
} else if (event.type.equals(ApkDownloader.EVENT_APK_DOWNLOAD_COMPLETE)) {
|
||||
installApk(downloadHandler.localFile(), downloadHandler.getApk().id);
|
||||
finished = true;
|
||||
} else if (event.type.equals(ApkDownloader.EVENT_APK_DOWNLOAD_CANCELLED)) {
|
||||
Toast.makeText(this, getString(R.string.download_cancelled), Toast.LENGTH_LONG).show();
|
||||
finished = true;
|
||||
}
|
||||
|
||||
if (finished) {
|
||||
|
@ -16,7 +16,6 @@ public interface ProgressListener {
|
||||
public static class Event implements Parcelable {
|
||||
|
||||
public static final int NO_VALUE = Integer.MIN_VALUE;
|
||||
public static final String PROGRESS_DATA_REPO = "repo";
|
||||
|
||||
public final String type;
|
||||
public final Bundle data;
|
||||
|
@ -128,11 +128,41 @@ public abstract class Downloader {
|
||||
InputStream input = null;
|
||||
try {
|
||||
input = inputStream();
|
||||
|
||||
// Getting the input stream is slow(ish) for HTTP downloads, so we'll check if
|
||||
// we were interrupted before proceeding to the download.
|
||||
throwExceptionIfInterrupted();
|
||||
|
||||
copyInputToOutputStream(inputStream());
|
||||
} finally {
|
||||
Utils.closeQuietly(outputStream);
|
||||
Utils.closeQuietly(input);
|
||||
}
|
||||
|
||||
// Even if we have completely downloaded the file, we should probably respect
|
||||
// the wishes of the user who wanted to cancel us.
|
||||
throwExceptionIfInterrupted();
|
||||
}
|
||||
|
||||
/**
|
||||
* In a synchronous download (the usual usage of the Downloader interface),
|
||||
* you will not be able to interrupt this because the thread will block
|
||||
* after you have called download(). However if you use the AsyncDownloadWrapper,
|
||||
* then it will use this mechanism to cancel the download.
|
||||
*
|
||||
* After every network operation that could take a while, we will check if an
|
||||
* interrupt occured during that blocking operation. The goal is to ensure we
|
||||
* don't move onto another slow, network operation if we have cancelled the
|
||||
* download.
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
private void throwExceptionIfInterrupted() throws InterruptedException {
|
||||
if (Thread.interrupted()) {
|
||||
// TODO: Do we need to provide more information to whoever needs it,
|
||||
// so they can, for example, remove any partially created files?
|
||||
Log.d(TAG, "Received interrupt, cancelling download");
|
||||
throw new InterruptedException();
|
||||
}
|
||||
}
|
||||
|
||||
protected void copyInputToOutputStream(InputStream input) throws IOException, InterruptedException {
|
||||
@ -140,21 +170,17 @@ public abstract class Downloader {
|
||||
byte[] buffer = new byte[Utils.BUFFER_SIZE];
|
||||
int bytesRead = 0;
|
||||
int totalBytes = totalDownloadSize();
|
||||
|
||||
// Getting the total download size could potentially take time, depending on how
|
||||
// it is implemented, so we may as well check this before we proceed.
|
||||
throwExceptionIfInterrupted();
|
||||
|
||||
sendProgress(bytesRead, totalBytes);
|
||||
while (true) {
|
||||
|
||||
// In a synchronous download (the usual usage of the Downloader interface),
|
||||
// you will not be able to interrupt this because the thread will block
|
||||
// after you have called download(). However if you use the AsyncDownloadWrapper,
|
||||
// then it will use this mechanism to cancel the download.
|
||||
if (Thread.interrupted()) {
|
||||
// TODO: Do we need to provide more information to whoever needs it,
|
||||
// so they can, for example, remove any partially created files?
|
||||
Log.d(TAG, "Received interrupt, cancelling download");
|
||||
throw new InterruptedException();
|
||||
}
|
||||
|
||||
int count = input.read(buffer);
|
||||
throwExceptionIfInterrupted();
|
||||
|
||||
bytesRead += count;
|
||||
sendProgress(bytesRead, totalBytes);
|
||||
if (count == -1) {
|
||||
|
@ -94,7 +94,7 @@ abstract public class RepoUpdater {
|
||||
|
||||
if (progressListener != null) { // interactive session, show progress
|
||||
Bundle data = new Bundle(1);
|
||||
data.putString(PROGRESS_DATA_REPO_ADDRESS, getIndexAddress());
|
||||
data.putString(PROGRESS_DATA_REPO_ADDRESS, repo.address);
|
||||
downloader.setProgressListener(progressListener, data);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user