create ProgressBufferedInputStream to get progress info while parsing XML

Might as well tap into the stream to get the byte counts, that's best
progress info I can think of when parsing a file.

This is a step towards a single progress bar for the whole process, instead
of showing one progress for downloading, another for parsing XML, then a
third for processing the new app info.
This commit is contained in:
Hans-Christoph Steiner 2015-06-18 15:07:04 -04:00
parent 4f2650cd47
commit 64d709c142
4 changed files with 68 additions and 18 deletions

View File

@ -211,7 +211,7 @@
- Percentage complete (int between 0-100)
-->
<string name="status_download">Downloading\n%2$s / %3$s (%4$d%%) from\n%1$s</string>
<string name="status_processing_xml">Processing application\n%2$d of %3$d from\n%1$s</string>
<string name="status_processing_xml">Processing\n%2$s / %3$s (%4$d%%) from\n%1$s</string>
<string name="status_connecting_to_repo">Connecting to\n%1$s</string>
<string name="status_checking_compatibility">Checking apps compatibility with your device…</string>
<string name="status_inserting">Saving application details (%1$d%%)</string>

View File

@ -0,0 +1,51 @@
package org.fdroid.fdroid;
import android.os.Bundle;
import org.fdroid.fdroid.data.Repo;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
public class ProgressBufferedInputStream extends BufferedInputStream {
private static final String TAG = "ProgressBufferedInputSt";
final Repo repo;
final ProgressListener progressListener;
final Bundle data;
final int totalBytes;
int currentBytes = 0;
/**
* Reports progress to the specified {@link ProgressListener}, with the
* progress based on the {@code totalBytes}.
*/
public ProgressBufferedInputStream(InputStream in, ProgressListener progressListener, Repo repo, int totalBytes)
throws IOException {
super(in);
this.progressListener = progressListener;
this.repo = repo;
this.data = new Bundle(1);
this.data.putString(RepoUpdater.PROGRESS_DATA_REPO_ADDRESS, repo.address);
this.totalBytes = totalBytes;
}
@Override
public int read(byte[] buffer, int byteOffset, int byteCount) throws IOException {
if (progressListener != null) {
currentBytes += byteCount;
/* don't send every change to keep things efficient. 333333 bytes to keep all
* the digits changing because it looks pretty, < 9000 since the reads won't
* line up exactly */
if (currentBytes % 333333 < 9000) {
progressListener.onProgress(
new ProgressListener.Event(
RepoUpdater.PROGRESS_TYPE_PROCESS_XML,
currentBytes, totalBytes, data));
}
}
return super.read(buffer, byteOffset, byteCount);
}
}

View File

@ -18,7 +18,6 @@ import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
@ -136,12 +135,13 @@ public class RepoUpdater {
if (repo.pubkey == null) // new repo, no signing certificate stored
storePubKey = true;
JarEntry indexEntry = null;
if (downloadedFile != null && downloadedFile.exists()) {
if (downloadedFile == null || !downloadedFile.exists())
throw new UpdateException(repo, downloadedFile + " does not exist!");
JarFile jarFile = new JarFile(downloadedFile, true);
indexEntry = (JarEntry) jarFile.getEntry("index.xml");
indexInputStream = new BufferedInputStream(jarFile.getInputStream(indexEntry));
}
JarEntry indexEntry = (JarEntry) jarFile.getEntry("index.xml");
indexInputStream = new ProgressBufferedInputStream(jarFile.getInputStream(indexEntry),
progressListener, repo, (int)indexEntry.getSize());
// Process the index...
final SAXParser parser = SAXParserFactory.newInstance().newSAXParser();

View File

@ -769,7 +769,6 @@ public class UpdateService extends IntentService implements ProgressListener {
Log.d(TAG, "Removing " + numDeleted + " apks that don't have any apks");
}
/**
* Received progress event from the RepoXMLHandler. It could be progress
* downloading from the repo, or perhaps processing the info from the repo.
@ -780,15 +779,15 @@ public class UpdateService extends IntentService implements ProgressListener {
// TODO: Switch to passing through Bundles of data with the event, rather than a repo address. They are
// now much more general purpose then just repo downloading.
String repoAddress = event.getData().getString(RepoUpdater.PROGRESS_DATA_REPO_ADDRESS);
switch (event.type) {
case Downloader.EVENT_PROGRESS:
String downloadedSize = Utils.getFriendlySize(event.progress);
String totalSize = Utils.getFriendlySize(event.total);
int percent = (int) ((double) event.progress / event.total * 100);
switch (event.type) {
case Downloader.EVENT_PROGRESS:
message = getString(R.string.status_download, repoAddress, downloadedSize, totalSize, percent);
break;
case RepoUpdater.PROGRESS_TYPE_PROCESS_XML:
message = getString(R.string.status_processing_xml, repoAddress, event.progress, event.total);
message = getString(R.string.status_processing_xml, repoAddress, downloadedSize, totalSize, percent);
break;
}
sendStatus(STATUS_INFO, message);