Refactor AsyncDownloader to be an interface.
The interface is used by both AsyncDownloadWrapper and AsyncDownloaderFromAndroid.
This commit is contained in:
parent
d0d287f668
commit
0a9941d93d
98
F-Droid/src/org/fdroid/fdroid/net/AsyncDownloadWrapper.java
Normal file
98
F-Droid/src/org/fdroid/fdroid/net/AsyncDownloadWrapper.java
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
package org.fdroid.fdroid.net;
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.os.Message;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
class AsyncDownloadWrapper extends Handler implements AsyncDownloader {
|
||||||
|
|
||||||
|
private static final String TAG = "AsyncDownloadWrapper";
|
||||||
|
|
||||||
|
private static final int MSG_DOWNLOAD_COMPLETE = 2;
|
||||||
|
private static final int MSG_DOWNLOAD_CANCELLED = 3;
|
||||||
|
private static final int MSG_ERROR = 4;
|
||||||
|
private static final String MSG_DATA = "data";
|
||||||
|
|
||||||
|
private final Downloader downloader;
|
||||||
|
private DownloadThread downloadThread = null;
|
||||||
|
|
||||||
|
private final Listener listener;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Normally the listener would be provided using a setListener method.
|
||||||
|
* However for the purposes of this async downloader, it doesn't make
|
||||||
|
* sense to have an async task without any way to notify the outside
|
||||||
|
* world about completion. Therefore, we require the listener as a
|
||||||
|
* parameter to the constructor.
|
||||||
|
*/
|
||||||
|
public AsyncDownloadWrapper(Downloader downloader, Listener listener) {
|
||||||
|
this.downloader = downloader;
|
||||||
|
this.listener = listener;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getBytesRead() {
|
||||||
|
return downloader.getBytesRead();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getTotalBytes() {
|
||||||
|
return downloader.getTotalBytes();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void download() {
|
||||||
|
downloadThread = new DownloadThread();
|
||||||
|
downloadThread.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void attemptCancel(boolean userRequested) {
|
||||||
|
if (downloadThread != null) {
|
||||||
|
downloadThread.interrupt();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Receives "messages" from the download thread, and passes them onto the
|
||||||
|
* relevant {@link AsyncDownloader.Listener}
|
||||||
|
*/
|
||||||
|
public void handleMessage(Message message) {
|
||||||
|
switch (message.arg1) {
|
||||||
|
case MSG_DOWNLOAD_COMPLETE:
|
||||||
|
listener.onDownloadComplete();
|
||||||
|
break;
|
||||||
|
case MSG_DOWNLOAD_CANCELLED:
|
||||||
|
listener.onDownloadCancelled();
|
||||||
|
break;
|
||||||
|
case MSG_ERROR:
|
||||||
|
listener.onErrorDownloading(message.getData().getString(MSG_DATA));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class DownloadThread extends Thread {
|
||||||
|
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
downloader.download();
|
||||||
|
sendMessage(MSG_DOWNLOAD_COMPLETE);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
sendMessage(MSG_DOWNLOAD_CANCELLED);
|
||||||
|
} catch (IOException e) {
|
||||||
|
Log.e(TAG, "I/O exception in download thread", e);
|
||||||
|
Bundle data = new Bundle(1);
|
||||||
|
data.putString(MSG_DATA, e.getLocalizedMessage());
|
||||||
|
Message message = new Message();
|
||||||
|
message.arg1 = MSG_ERROR;
|
||||||
|
message.setData(data);
|
||||||
|
AsyncDownloadWrapper.this.sendMessage(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sendMessage(int messageType) {
|
||||||
|
Message message = new Message();
|
||||||
|
message.arg1 = messageType;
|
||||||
|
AsyncDownloadWrapper.this.sendMessage(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -9,106 +9,17 @@ import org.fdroid.fdroid.ProgressListener;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
/**
|
public interface AsyncDownloader {
|
||||||
* Given a {@link org.fdroid.fdroid.net.Downloader}, this wrapper will conduct the download operation on a
|
|
||||||
* separate thread. All progress/status/error/etc events will be forwarded from that thread to the thread
|
|
||||||
* that {@link AsyncDownloader#download()} was invoked on. If you want to respond with UI feedback
|
|
||||||
* to these events, it is important that you execute the download method of this class from the UI thread.
|
|
||||||
* That way, all forwarded events will be handled on that thread.
|
|
||||||
*/
|
|
||||||
@SuppressWarnings("serial")
|
|
||||||
public class AsyncDownloader extends Handler {
|
|
||||||
|
|
||||||
private static final String TAG = "AsyncDownloadWrapper";
|
interface Listener extends ProgressListener {
|
||||||
|
|
||||||
private static final int MSG_DOWNLOAD_COMPLETE = 2;
|
|
||||||
private static final int MSG_DOWNLOAD_CANCELLED = 3;
|
|
||||||
private static final int MSG_ERROR = 4;
|
|
||||||
private static final String MSG_DATA = "data";
|
|
||||||
|
|
||||||
private final Downloader downloader;
|
|
||||||
private final Listener listener;
|
|
||||||
private DownloadThread downloadThread = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Normally the listener would be provided using a setListener method.
|
|
||||||
* However for the purposes of this async downloader, it doesn't make
|
|
||||||
* sense to have an async task without any way to notify the outside
|
|
||||||
* world about completion. Therefore, we require the listener as a
|
|
||||||
* parameter to the constructor.
|
|
||||||
*/
|
|
||||||
public AsyncDownloader(Downloader downloader, Listener listener) {
|
|
||||||
this.downloader = downloader;
|
|
||||||
this.listener = listener;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void download() {
|
|
||||||
downloadThread = new DownloadThread();
|
|
||||||
downloadThread.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void attemptCancel(boolean userRequested) {
|
|
||||||
if (downloadThread != null) {
|
|
||||||
downloadThread.interrupt();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Receives "messages" from the download thread, and passes them onto the
|
|
||||||
* relevant {@link AsyncDownloader.Listener}
|
|
||||||
* @param message
|
|
||||||
*/
|
|
||||||
public void handleMessage(Message message) {
|
|
||||||
switch (message.arg1) {
|
|
||||||
case MSG_DOWNLOAD_COMPLETE:
|
|
||||||
listener.onDownloadComplete();
|
|
||||||
break;
|
|
||||||
case MSG_DOWNLOAD_CANCELLED:
|
|
||||||
listener.onDownloadCancelled();
|
|
||||||
break;
|
|
||||||
case MSG_ERROR:
|
|
||||||
listener.onErrorDownloading(message.getData().getString(MSG_DATA));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getBytesRead() {
|
|
||||||
return downloader.getBytesRead();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getTotalBytes() {
|
|
||||||
return downloader.getTotalBytes();
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface Listener extends ProgressListener {
|
|
||||||
void onErrorDownloading(String localisedExceptionDetails);
|
void onErrorDownloading(String localisedExceptionDetails);
|
||||||
void onDownloadComplete();
|
void onDownloadComplete();
|
||||||
void onDownloadCancelled();
|
void onDownloadCancelled();
|
||||||
}
|
}
|
||||||
|
|
||||||
private class DownloadThread extends Thread {
|
int getBytesRead();
|
||||||
|
int getTotalBytes();
|
||||||
|
void download();
|
||||||
|
void attemptCancel(boolean userRequested);
|
||||||
|
|
||||||
public void run() {
|
|
||||||
try {
|
|
||||||
downloader.download();
|
|
||||||
sendMessage(MSG_DOWNLOAD_COMPLETE);
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
sendMessage(MSG_DOWNLOAD_CANCELLED);
|
|
||||||
} catch (IOException e) {
|
|
||||||
Log.e(TAG, "I/O exception in download thread", e);
|
|
||||||
Bundle data = new Bundle(1);
|
|
||||||
data.putString(MSG_DATA, e.getLocalizedMessage());
|
|
||||||
Message message = new Message();
|
|
||||||
message.arg1 = MSG_ERROR;
|
|
||||||
message.setData(data);
|
|
||||||
AsyncDownloader.this.sendMessage(message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void sendMessage(int messageType) {
|
|
||||||
Message message = new Message();
|
|
||||||
message.arg1 = messageType;
|
|
||||||
AsyncDownloader.this.sendMessage(message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,7 @@ import java.io.OutputStream;
|
|||||||
* A downloader that uses Android's DownloadManager to perform a download.
|
* A downloader that uses Android's DownloadManager to perform a download.
|
||||||
*/
|
*/
|
||||||
@TargetApi(Build.VERSION_CODES.GINGERBREAD)
|
@TargetApi(Build.VERSION_CODES.GINGERBREAD)
|
||||||
public class AsyncDownloaderFromAndroid extends AsyncDownloader {
|
public class AsyncDownloaderFromAndroid implements AsyncDownloader {
|
||||||
private final Context context;
|
private final Context context;
|
||||||
private final DownloadManager dm;
|
private final DownloadManager dm;
|
||||||
private File localFile;
|
private File localFile;
|
||||||
@ -42,7 +42,6 @@ public class AsyncDownloaderFromAndroid extends AsyncDownloader {
|
|||||||
* parameter to the constructor.
|
* parameter to the constructor.
|
||||||
*/
|
*/
|
||||||
public AsyncDownloaderFromAndroid(Context context, Listener listener, String appName, String appId, String remoteAddress, File localFile) {
|
public AsyncDownloaderFromAndroid(Context context, Listener listener, String appName, String appId, String remoteAddress, File localFile) {
|
||||||
super(null, listener);
|
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.appName = appName;
|
this.appName = appName;
|
||||||
this.appId = appId;
|
this.appId = appId;
|
||||||
|
@ -5,7 +5,6 @@ import android.os.Build;
|
|||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.MalformedURLException;
|
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
|
||||||
public class DownloaderFactory {
|
public class DownloaderFactory {
|
||||||
@ -62,7 +61,7 @@ public class DownloaderFactory {
|
|||||||
if (canUseDownloadManager(url)) {
|
if (canUseDownloadManager(url)) {
|
||||||
return new AsyncDownloaderFromAndroid(context, listener, title, id, url.toString(), destFile);
|
return new AsyncDownloaderFromAndroid(context, listener, title, id, url.toString(), destFile);
|
||||||
} else {
|
} else {
|
||||||
return new AsyncDownloader(create(context, url, destFile), listener);
|
return new AsyncDownloadWrapper(create(context, url, destFile), listener);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user