Revision 0a9941d9 F-Droid/src/org/fdroid/fdroid/net/AsyncDownloader.java
F-Droid/src/org/fdroid/fdroid/net/AsyncDownloader.java | ||
---|---|---|
9 | 9 |
|
10 | 10 |
import java.io.IOException; |
11 | 11 |
|
12 |
/** |
|
13 |
* Given a {@link org.fdroid.fdroid.net.Downloader}, this wrapper will conduct the download operation on a |
|
14 |
* separate thread. All progress/status/error/etc events will be forwarded from that thread to the thread |
|
15 |
* that {@link AsyncDownloader#download()} was invoked on. If you want to respond with UI feedback |
|
16 |
* to these events, it is important that you execute the download method of this class from the UI thread. |
|
17 |
* That way, all forwarded events will be handled on that thread. |
|
18 |
*/ |
|
19 |
@SuppressWarnings("serial") |
|
20 |
public class AsyncDownloader extends Handler { |
|
12 |
public interface AsyncDownloader { |
|
21 | 13 |
|
22 |
private static final String TAG = "AsyncDownloadWrapper"; |
|
23 |
|
|
24 |
private static final int MSG_DOWNLOAD_COMPLETE = 2; |
|
25 |
private static final int MSG_DOWNLOAD_CANCELLED = 3; |
|
26 |
private static final int MSG_ERROR = 4; |
|
27 |
private static final String MSG_DATA = "data"; |
|
28 |
|
|
29 |
private final Downloader downloader; |
|
30 |
private final Listener listener; |
|
31 |
private DownloadThread downloadThread = null; |
|
32 |
|
|
33 |
/** |
|
34 |
* Normally the listener would be provided using a setListener method. |
|
35 |
* However for the purposes of this async downloader, it doesn't make |
|
36 |
* sense to have an async task without any way to notify the outside |
|
37 |
* world about completion. Therefore, we require the listener as a |
|
38 |
* parameter to the constructor. |
|
39 |
*/ |
|
40 |
public AsyncDownloader(Downloader downloader, Listener listener) { |
|
41 |
this.downloader = downloader; |
|
42 |
this.listener = listener; |
|
43 |
} |
|
44 |
|
|
45 |
public void download() { |
|
46 |
downloadThread = new DownloadThread(); |
|
47 |
downloadThread.start(); |
|
48 |
} |
|
49 |
|
|
50 |
public void attemptCancel(boolean userRequested) { |
|
51 |
if (downloadThread != null) { |
|
52 |
downloadThread.interrupt(); |
|
53 |
} |
|
54 |
} |
|
55 |
|
|
56 |
/** |
|
57 |
* Receives "messages" from the download thread, and passes them onto the |
|
58 |
* relevant {@link AsyncDownloader.Listener} |
|
59 |
* @param message |
|
60 |
*/ |
|
61 |
public void handleMessage(Message message) { |
|
62 |
switch (message.arg1) { |
|
63 |
case MSG_DOWNLOAD_COMPLETE: |
|
64 |
listener.onDownloadComplete(); |
|
65 |
break; |
|
66 |
case MSG_DOWNLOAD_CANCELLED: |
|
67 |
listener.onDownloadCancelled(); |
|
68 |
break; |
|
69 |
case MSG_ERROR: |
|
70 |
listener.onErrorDownloading(message.getData().getString(MSG_DATA)); |
|
71 |
break; |
|
72 |
} |
|
73 |
} |
|
74 |
|
|
75 |
public int getBytesRead() { |
|
76 |
return downloader.getBytesRead(); |
|
77 |
} |
|
78 |
|
|
79 |
public int getTotalBytes() { |
|
80 |
return downloader.getTotalBytes(); |
|
81 |
} |
|
82 |
|
|
83 |
public interface Listener extends ProgressListener { |
|
14 |
interface Listener extends ProgressListener { |
|
84 | 15 |
void onErrorDownloading(String localisedExceptionDetails); |
85 | 16 |
void onDownloadComplete(); |
86 | 17 |
void onDownloadCancelled(); |
87 | 18 |
} |
88 | 19 |
|
89 |
private class DownloadThread extends Thread { |
|
20 |
int getBytesRead(); |
|
21 |
int getTotalBytes(); |
|
22 |
void download(); |
|
23 |
void attemptCancel(boolean userRequested); |
|
90 | 24 |
|
91 |
public void run() { |
|
92 |
try { |
|
93 |
downloader.download(); |
|
94 |
sendMessage(MSG_DOWNLOAD_COMPLETE); |
|
95 |
} catch (InterruptedException e) { |
|
96 |
sendMessage(MSG_DOWNLOAD_CANCELLED); |
|
97 |
} catch (IOException e) { |
|
98 |
Log.e(TAG, "I/O exception in download thread", e); |
|
99 |
Bundle data = new Bundle(1); |
|
100 |
data.putString(MSG_DATA, e.getLocalizedMessage()); |
|
101 |
Message message = new Message(); |
|
102 |
message.arg1 = MSG_ERROR; |
|
103 |
message.setData(data); |
|
104 |
AsyncDownloader.this.sendMessage(message); |
|
105 |
} |
|
106 |
} |
|
107 |
|
|
108 |
private void sendMessage(int messageType) { |
|
109 |
Message message = new Message(); |
|
110 |
message.arg1 = messageType; |
|
111 |
AsyncDownloader.this.sendMessage(message); |
|
112 |
} |
|
113 |
} |
|
114 | 25 |
} |
Also available in: Unified diff