Revision 0a9941d9 F-Droid/src/org/fdroid/fdroid/net/AsyncDownloader.java

View differences:

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