Pass parameter in RxJava for OnCompleted in Android
I am uploading multiple images using RxJava. Besides uploading, I also show the progress for each uploaded file. My problem is that I need to know when the file is fully loaded (currently, the last part of the loaded progress is not emitted). Since I can upload multiple files at the same time, I need to pass the mediaId of the uploaded file. Or I should be able to get the last part of the download progress. How can i do this?
downloadThread = new Downloader(media.getMediaUrl(), media.getId(), context);
downloadThread.start();
downloadThread.getProgressObservable()
.sample(30, java.util.concurrent.TimeUnit.MILLISECONDS)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Action1<DownloadProgressEvent>() {
@Override
public void call(DownloadProgressEvent event) {
ProgressBar downloadProgress = (ProgressBar) view.findViewById(R.id.download_progress);
if (event.getTotal() > 0) {
int downloadPercent = (int) ((event.getLoaded() * 100l) / event.getTotal());
downloadProgress.setProgress(downloadPercent);
Log.d(TAG, "download progress: " + String.format("%s / %s /percent: %s / mediaId: %s", event.getLoadedBytes(), event.getTotalBytes(), downloadPercent, event.getMediaId()));
}
}
});
}
Code from the Downloader class.
public void loadInBackground() {
try {
URL toDownload = new URL(url);
HttpURLConnection urlConnection = (HttpURLConnection) toDownload.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.connect();
String mimeType = MimeTypeMap.getFileExtensionFromUrl(url);
File outFile = new File(helper.getTmpFolder() + "/" + helper.generateUniqueName() + "test." + mimeType);
FileOutputStream fileOutput = new FileOutputStream(outFile);
InputStream inputStream = urlConnection.getInputStream();
totalSize = urlConnection.getContentLength();
loadedSize = 0;
byte[] buffer = new byte[1024];
int bufferLength = 0; //used to store a temporary size of the buffer
while (!killed && (bufferLength = inputStream.read(buffer)) > 0) {
while(!running && !killed) {
Thread.sleep(500);
}
if (!killed) {
fileOutput.write(buffer, 0, bufferLength);
loadedSize += bufferLength;
reportProgress();
}
}
fileOutput.close();
if (killed && outFile.exists()) {
outFile.delete();
}
progressSubject.onCompleted();
} catch (MalformedURLException e) {
e.printStackTrace();
progressSubject.onError(e);
} catch (IOException e) {
e.printStackTrace();
progressSubject.onError(e);
} catch (InterruptedException e) {
e.printStackTrace();
progressSubject.onError(e);
}
}
private void reportProgress() {
progressSubject.onNext(new DownloadProgressEvent(loadedSize, totalSize, mediaId));
}
@Override
public void run() {
loadInBackground();
}
public Subject<DownloadProgressEvent, DownloadProgressEvent> getProgressObservable() {
return progressSubject;
}
+3
source to share
1 answer
After finding out that I cannot pass the parameter via onCompleted, I solved my problem as follows.
downloadThread.getProgressObservable()
.sample(30, java.util.concurrent.TimeUnit.MILLISECONDS)
.observeOn(AndroidSchedulers.mainThread())
.doOnCompleted(new Action0() {
@Override
public void call() {
downloadProgress.setProgress(100);
putGoodQualityThumbnail(media, view);;
}
})
.subscribe(new Action1<DownloadProgressEvent>() {
@Override
public void call(DownloadProgressEvent event) {
if (event.getTotal() > 0) {
int downloadPercent = (int) ((event.getLoaded() * 100l) / event.getTotal());
downloadProgress.setProgress(downloadPercent);
}
}
});
0
source to share