Rough guess at what ApkDownloader refactor could look like.
This commit is contained in:
		
							parent
							
								
									c4b0eb9b51
								
							
						
					
					
						commit
						a44ce0e4e7
					
				
							
								
								
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@ -6,6 +6,6 @@
 | 
			
		||||
/build.xml
 | 
			
		||||
*~
 | 
			
		||||
/.idea/
 | 
			
		||||
/*.iml
 | 
			
		||||
*.iml
 | 
			
		||||
out
 | 
			
		||||
/.settings/
 | 
			
		||||
 | 
			
		||||
@ -20,37 +20,29 @@
 | 
			
		||||
 | 
			
		||||
package org.fdroid.fdroid;
 | 
			
		||||
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.io.FileOutputStream;
 | 
			
		||||
import java.io.InputStream;
 | 
			
		||||
import java.io.OutputStream;
 | 
			
		||||
import java.net.URL;
 | 
			
		||||
import java.io.*;
 | 
			
		||||
 | 
			
		||||
import android.util.Log;
 | 
			
		||||
import org.fdroid.fdroid.data.Apk;
 | 
			
		||||
import org.fdroid.fdroid.net.HttpDownloader;
 | 
			
		||||
 | 
			
		||||
public class ApkDownloader extends Thread {
 | 
			
		||||
 | 
			
		||||
    public static final int EVENT_APK_DOWNLOAD_COMPLETE = 100;
 | 
			
		||||
    public static final int EVENT_ERROR_HASH_MISMATCH = 101;
 | 
			
		||||
    public static final int EVENT_ERROR_DOWNLOAD_FAILED = 102;
 | 
			
		||||
    public static final int EVENT_ERROR_UNKNOWN = 103;
 | 
			
		||||
    private Apk curapk;
 | 
			
		||||
    private String repoaddress;
 | 
			
		||||
    private String filename;
 | 
			
		||||
    private File destdir;
 | 
			
		||||
    private File localfile;
 | 
			
		||||
 | 
			
		||||
    public static enum Status {
 | 
			
		||||
        STARTING, RUNNING, ERROR, DONE, CANCELLED
 | 
			
		||||
    }
 | 
			
		||||
    private ProgressListener listener;
 | 
			
		||||
 | 
			
		||||
    public static enum Error {
 | 
			
		||||
        CORRUPT, UNKNOWN
 | 
			
		||||
    public void setProgressListener(ProgressListener listener) {
 | 
			
		||||
        this.listener = listener;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private Status status = Status.STARTING;
 | 
			
		||||
    private Error error;
 | 
			
		||||
    private int progress;
 | 
			
		||||
    private int max;
 | 
			
		||||
    private String errorMessage;
 | 
			
		||||
 | 
			
		||||
    // Constructor - creates a Downloader to download the given Apk,
 | 
			
		||||
    // which must have its detail populated.
 | 
			
		||||
    ApkDownloader(Apk apk, String repoaddress, File destdir) {
 | 
			
		||||
@ -59,50 +51,19 @@ public class ApkDownloader extends Thread {
 | 
			
		||||
        this.destdir = destdir;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public synchronized Status getStatus() {
 | 
			
		||||
        return status;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Current progress and maximum value for progress dialog
 | 
			
		||||
    public synchronized int getProgress() {
 | 
			
		||||
        return progress;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public synchronized int getMax() {
 | 
			
		||||
        return max;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Error code and error message, only valid if status is ERROR
 | 
			
		||||
    public synchronized Error getErrorType() {
 | 
			
		||||
        return error;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public synchronized String getErrorMessage() {
 | 
			
		||||
        return errorMessage;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // The URL being downloaded or path to a cached file
 | 
			
		||||
    public synchronized String remoteFile() {
 | 
			
		||||
        return filename;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // The downloaded APK. Valid only when getStatus() has returned STATUS.DONE.
 | 
			
		||||
    public File localFile() {
 | 
			
		||||
        return localfile;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // The APK being downloaded
 | 
			
		||||
    public synchronized Apk getApk() {
 | 
			
		||||
        return curapk;
 | 
			
		||||
    public String remoteFile() {
 | 
			
		||||
         return repoaddress + "/" + curapk.apkName.replace(" ", "%20");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void run() {
 | 
			
		||||
        localfile = new File(destdir, curapk.apkName);
 | 
			
		||||
 | 
			
		||||
        InputStream input = null;
 | 
			
		||||
        OutputStream output = null;
 | 
			
		||||
        String apkname = curapk.apkName;
 | 
			
		||||
        localfile = new File(destdir, apkname);
 | 
			
		||||
        try {
 | 
			
		||||
 | 
			
		||||
            // See if we already have this apk cached...
 | 
			
		||||
@ -111,12 +72,7 @@ public class ApkDownloader extends Thread {
 | 
			
		||||
                Hasher hash = new Hasher(curapk.hashType, localfile);
 | 
			
		||||
                if (hash.match(curapk.hash)) {
 | 
			
		||||
                    Log.d("FDroid", "Using cached apk at " + localfile);
 | 
			
		||||
                    synchronized (this) {
 | 
			
		||||
                        progress = 1;
 | 
			
		||||
                        max = 1;
 | 
			
		||||
                        status = Status.DONE;
 | 
			
		||||
                        return;
 | 
			
		||||
                    }
 | 
			
		||||
                    return;
 | 
			
		||||
                } else {
 | 
			
		||||
                    Log.d("FDroid", "Not using cached apk at " + localfile);
 | 
			
		||||
                    localfile.delete();
 | 
			
		||||
@ -124,72 +80,45 @@ public class ApkDownloader extends Thread {
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // If we haven't got the apk locally, we'll have to download it...
 | 
			
		||||
            String remotefile;
 | 
			
		||||
            remotefile = repoaddress + "/" + apkname.replace(" ", "%20");
 | 
			
		||||
            Log.d("FDroid", "Downloading apk from " + remotefile);
 | 
			
		||||
            synchronized (this) {
 | 
			
		||||
                filename = remotefile;
 | 
			
		||||
                progress = 0;
 | 
			
		||||
                max = curapk.size;
 | 
			
		||||
                status = Status.RUNNING;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            input = new URL(remotefile).openStream();
 | 
			
		||||
            output = new FileOutputStream(localfile);
 | 
			
		||||
            byte data[] = new byte[Utils.BUFFER_SIZE];
 | 
			
		||||
            while (true) {
 | 
			
		||||
                if (isInterrupted()) {
 | 
			
		||||
                    Log.d("FDroid", "Download cancelled!");
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
                int count = input.read(data);
 | 
			
		||||
                if (count == -1) {
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
                output.write(data, 0, count);
 | 
			
		||||
                synchronized (this) {
 | 
			
		||||
                    progress += count;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            HttpDownloader downloader = new HttpDownloader(remoteFile(), localfile);
 | 
			
		||||
            downloader.setProgressListener(listener);
 | 
			
		||||
 | 
			
		||||
            if (isInterrupted()) {
 | 
			
		||||
                localfile.delete();
 | 
			
		||||
                synchronized (this) {
 | 
			
		||||
                    status = Status.CANCELLED;
 | 
			
		||||
                }
 | 
			
		||||
            Log.d("FDroid", "Downloading apk from " + remoteFile());
 | 
			
		||||
            int httpStatus = downloader.downloadHttpFile();
 | 
			
		||||
 | 
			
		||||
            if (httpStatus != 200 || !localfile.exists()) {
 | 
			
		||||
                sendProgress(EVENT_ERROR_DOWNLOAD_FAILED);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            Hasher hash = new Hasher(curapk.hashType, localfile);
 | 
			
		||||
            if (!hash.match(curapk.hash)) {
 | 
			
		||||
                synchronized (this) {
 | 
			
		||||
                    Log.d("FDroid", "Downloaded file hash of " + hash.getHash()
 | 
			
		||||
                            + " did not match repo's " + curapk.hash);
 | 
			
		||||
                    // No point keeping a bad file, whether we're
 | 
			
		||||
                    // caching or not.
 | 
			
		||||
                    localfile.delete();
 | 
			
		||||
                    error = Error.CORRUPT;
 | 
			
		||||
                    errorMessage = null;
 | 
			
		||||
                    status = Status.ERROR;
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
                Log.d("FDroid", "Downloaded file hash of " + hash.getHash()
 | 
			
		||||
                        + " did not match repo's " + curapk.hash);
 | 
			
		||||
                // No point keeping a bad file, whether we're
 | 
			
		||||
                // caching or not.
 | 
			
		||||
                localfile.delete();
 | 
			
		||||
                sendProgress(EVENT_ERROR_HASH_MISMATCH);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            Log.e("FDroid", "Download failed:\n" + Log.getStackTraceString(e));
 | 
			
		||||
            synchronized (this) {
 | 
			
		||||
            if (localfile.exists()) {
 | 
			
		||||
                localfile.delete();
 | 
			
		||||
                error = Error.UNKNOWN;
 | 
			
		||||
                errorMessage = e.toString();
 | 
			
		||||
                status = Status.ERROR;
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
        } finally {
 | 
			
		||||
            Utils.closeQuietly(output);
 | 
			
		||||
            Utils.closeQuietly(input);
 | 
			
		||||
            sendProgress(EVENT_ERROR_UNKNOWN);
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Log.d("FDroid", "Download finished: " + localfile);
 | 
			
		||||
        synchronized (this) {
 | 
			
		||||
            status = Status.DONE;
 | 
			
		||||
        sendProgress(EVENT_APK_DOWNLOAD_COMPLETE);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void sendProgress(int type) {
 | 
			
		||||
        if (listener != null) {
 | 
			
		||||
            listener.onProgress(new ProgressListener.Event(type));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -26,6 +26,7 @@ import org.fdroid.fdroid.data.*;
 | 
			
		||||
import org.fdroid.fdroid.installer.Installer;
 | 
			
		||||
import org.fdroid.fdroid.installer.Installer.AndroidNotCompatibleException;
 | 
			
		||||
import org.fdroid.fdroid.installer.Installer.InstallerCallback;
 | 
			
		||||
import org.fdroid.fdroid.net.Downloader;
 | 
			
		||||
import org.xml.sax.XMLReader;
 | 
			
		||||
 | 
			
		||||
import android.app.AlertDialog;
 | 
			
		||||
@ -394,10 +395,6 @@ public class AppDetails extends ListActivity {
 | 
			
		||||
        updateViews();
 | 
			
		||||
 | 
			
		||||
        MenuManager.create(this).invalidateOptionsMenu();
 | 
			
		||||
 | 
			
		||||
        if (downloadHandler != null) {
 | 
			
		||||
            downloadHandler.startUpdates();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
@ -405,9 +402,6 @@ public class AppDetails extends ListActivity {
 | 
			
		||||
        if (myAppObserver != null) {
 | 
			
		||||
            getContentResolver().unregisterContentObserver(myAppObserver);
 | 
			
		||||
        }
 | 
			
		||||
        if (downloadHandler != null) {
 | 
			
		||||
            downloadHandler.stopUpdates();
 | 
			
		||||
        }
 | 
			
		||||
        if (app != null && (app.ignoreAllUpdates != startingIgnoreAll
 | 
			
		||||
                || app.ignoreThisUpdate != startingIgnoreThis)) {
 | 
			
		||||
            setIgnoreUpdates(app.id, app.ignoreAllUpdates, app.ignoreThisUpdate);
 | 
			
		||||
@ -1039,7 +1033,7 @@ public class AppDetails extends ListActivity {
 | 
			
		||||
        shareIntent.setType("text/plain");
 | 
			
		||||
 | 
			
		||||
        shareIntent.putExtra(Intent.EXTRA_SUBJECT, app.name);
 | 
			
		||||
        shareIntent.putExtra(Intent.EXTRA_TEXT, app.name+" ("+app.summary+") - https://f-droid.org/app/"+app.id);
 | 
			
		||||
        shareIntent.putExtra(Intent.EXTRA_TEXT, app.name + " (" + app.summary + ") - https://f-droid.org/app/" + app.id);
 | 
			
		||||
 | 
			
		||||
        startActivity(Intent.createChooser(shareIntent, getString(R.string.menu_share)));
 | 
			
		||||
    }
 | 
			
		||||
@ -1071,81 +1065,61 @@ public class AppDetails extends ListActivity {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Handler used to update the progress dialog while downloading.
 | 
			
		||||
    private class DownloadHandler extends Handler {
 | 
			
		||||
    private class DownloadHandler extends Handler implements ProgressListener {
 | 
			
		||||
        private ApkDownloader download;
 | 
			
		||||
        private ProgressDialog pd;
 | 
			
		||||
        private boolean updating;
 | 
			
		||||
        private String id;
 | 
			
		||||
 | 
			
		||||
        public DownloadHandler(Apk apk, String repoaddress, File destdir) {
 | 
			
		||||
            id = apk.id;
 | 
			
		||||
            download = new ApkDownloader(apk, repoaddress, destdir);
 | 
			
		||||
            download.start();
 | 
			
		||||
            startUpdates();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public DownloadHandler(DownloadHandler oldHandler) {
 | 
			
		||||
            if (oldHandler != null) {
 | 
			
		||||
                download = oldHandler.download;
 | 
			
		||||
            }
 | 
			
		||||
            startUpdates();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public boolean updateProgress() {
 | 
			
		||||
        public void onProgress(ProgressListener.Event event) {
 | 
			
		||||
            boolean finished = false;
 | 
			
		||||
            switch (download.getStatus()) {
 | 
			
		||||
            case RUNNING:
 | 
			
		||||
                if (pd == null) {
 | 
			
		||||
                    pd = createProgressDialog(download.remoteFile(),
 | 
			
		||||
                            download.getProgress(), download.getMax());
 | 
			
		||||
                } else {
 | 
			
		||||
                    pd.setProgress(download.getProgress());
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
            case ERROR:
 | 
			
		||||
                if (pd != null)
 | 
			
		||||
                    pd.dismiss();
 | 
			
		||||
                String text;
 | 
			
		||||
                if (download.getErrorType() == ApkDownloader.Error.CORRUPT)
 | 
			
		||||
                    text = getString(R.string.corrupt_download);
 | 
			
		||||
                else
 | 
			
		||||
                    text = download.getErrorMessage();
 | 
			
		||||
                Toast.makeText(AppDetails.this, text, Toast.LENGTH_LONG).show();
 | 
			
		||||
                finished = true;
 | 
			
		||||
                break;
 | 
			
		||||
            case DONE:
 | 
			
		||||
                if (pd != null)
 | 
			
		||||
                    pd.dismiss();
 | 
			
		||||
                installApk(download.localFile(), id);
 | 
			
		||||
                finished = true;
 | 
			
		||||
                break;
 | 
			
		||||
            case CANCELLED:
 | 
			
		||||
                Toast.makeText(AppDetails.this,
 | 
			
		||||
                        getString(R.string.download_cancelled),
 | 
			
		||||
                        Toast.LENGTH_SHORT).show();
 | 
			
		||||
                finished = true;
 | 
			
		||||
                break;
 | 
			
		||||
            default:
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            return finished;
 | 
			
		||||
        }
 | 
			
		||||
            switch (event.type) {
 | 
			
		||||
                case Downloader.EVENT_PROGRESS:
 | 
			
		||||
                    if (pd == null) {
 | 
			
		||||
                        pd = createProgressDialog(download.remoteFile(),
 | 
			
		||||
                                event.progress, event.total);
 | 
			
		||||
                    } else {
 | 
			
		||||
                        pd.setProgress(event.progress);
 | 
			
		||||
                    }
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
        public void startUpdates() {
 | 
			
		||||
            if (!updating) {
 | 
			
		||||
                updating = true;
 | 
			
		||||
                sendEmptyMessage(0);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
                case ApkDownloader.EVENT_ERROR_DOWNLOAD_FAILED:
 | 
			
		||||
                case ApkDownloader.EVENT_ERROR_HASH_MISMATCH:
 | 
			
		||||
                case ApkDownloader.EVENT_ERROR_UNKNOWN:
 | 
			
		||||
                    String text;
 | 
			
		||||
                    if (event.type == ApkDownloader.EVENT_ERROR_HASH_MISMATCH)
 | 
			
		||||
                        text = getString(R.string.corrupt_download);
 | 
			
		||||
                    else
 | 
			
		||||
                        text = getString(R.string.details_notinstalled);
 | 
			
		||||
                    Toast.makeText(AppDetails.this, text, Toast.LENGTH_LONG).show();
 | 
			
		||||
                    finished = true;
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
        public void stopUpdates() {
 | 
			
		||||
            updating = false;
 | 
			
		||||
            removeMessages(0);
 | 
			
		||||
                case ApkDownloader.EVENT_APK_DOWNLOAD_COMPLETE:
 | 
			
		||||
                    installApk(download.localFile(), id);
 | 
			
		||||
                    finished = true;
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (finished) {
 | 
			
		||||
                destroy();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void cancel() {
 | 
			
		||||
            if (download != null)
 | 
			
		||||
                download.interrupt();
 | 
			
		||||
            // TODO: Re-implement...
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void destroy() {
 | 
			
		||||
@ -1155,24 +1129,10 @@ public class AppDetails extends ListActivity {
 | 
			
		||||
                pd.dismiss();
 | 
			
		||||
                pd = null;
 | 
			
		||||
            }
 | 
			
		||||
            // Cancel any scheduled updates so that we don't
 | 
			
		||||
            // accidentally recreate the progress dialog.
 | 
			
		||||
            stopUpdates();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Repeatedly run updateProgress() until it's finished.
 | 
			
		||||
        @Override
 | 
			
		||||
        public void handleMessage(Message msg) {
 | 
			
		||||
            if (download == null)
 | 
			
		||||
                return;
 | 
			
		||||
            boolean finished = updateProgress();
 | 
			
		||||
            if (finished)
 | 
			
		||||
                download = null;
 | 
			
		||||
            else
 | 
			
		||||
                sendMessageDelayed(obtainMessage(), 50);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
 | 
			
		||||
        // handle cases for install manager first
 | 
			
		||||
 | 
			
		||||
@ -10,15 +10,28 @@ public abstract class Downloader {
 | 
			
		||||
    private OutputStream outputStream;
 | 
			
		||||
    private ProgressListener progressListener = null;
 | 
			
		||||
    private ProgressListener.Event progressEvent = null;
 | 
			
		||||
    private final File outputFile;
 | 
			
		||||
    private File outputFile;
 | 
			
		||||
 | 
			
		||||
    public static final int EVENT_PROGRESS = 1;
 | 
			
		||||
 | 
			
		||||
    public abstract InputStream inputStream() throws IOException;
 | 
			
		||||
 | 
			
		||||
    // The context is required for opening the file to write to.
 | 
			
		||||
    public Downloader(String destFile, Context ctx)
 | 
			
		||||
            throws FileNotFoundException, MalformedURLException {
 | 
			
		||||
        outputStream = ctx.openFileOutput(destFile, Context.MODE_PRIVATE);
 | 
			
		||||
        outputFile   = new File(ctx.getFilesDir() + File.separator + destFile);
 | 
			
		||||
        this(new File(ctx.getFilesDir() + File.separator + destFile));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // The context is required for opening the file to write to.
 | 
			
		||||
    public Downloader(Context ctx) throws IOException {
 | 
			
		||||
        this(File.createTempFile("dl-", "", ctx.getCacheDir()));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Downloader(File destFile)
 | 
			
		||||
            throws FileNotFoundException, MalformedURLException {
 | 
			
		||||
        // http://developer.android.com/guide/topics/data/data-storage.html#InternalCache
 | 
			
		||||
        outputFile = destFile;
 | 
			
		||||
        outputStream = new FileOutputStream(outputFile);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@ -26,10 +39,7 @@ public abstract class Downloader {
 | 
			
		||||
     * you are done*.
 | 
			
		||||
     * @see org.fdroid.fdroid.net.Downloader#getFile()
 | 
			
		||||
     */
 | 
			
		||||
    public Downloader(Context ctx) throws IOException {
 | 
			
		||||
        // http://developer.android.com/guide/topics/data/data-storage.html#InternalCache
 | 
			
		||||
        outputFile = File.createTempFile("dl-", "", ctx.getCacheDir());
 | 
			
		||||
        outputStream = new FileOutputStream(outputFile);
 | 
			
		||||
    public Downloader(File destFile, Context ctx) throws IOException {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Downloader(OutputStream output)
 | 
			
		||||
@ -38,6 +48,11 @@ public abstract class Downloader {
 | 
			
		||||
        outputFile   = null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setProgressListener(ProgressListener listener) {
 | 
			
		||||
        this.progressListener = listener;
 | 
			
		||||
        this.progressEvent = new ProgressListener.Event(EVENT_PROGRESS, totalDownloadSize());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setProgressListener(ProgressListener progressListener,
 | 
			
		||||
                                    ProgressListener.Event progressEvent) {
 | 
			
		||||
        this.progressListener = progressListener;
 | 
			
		||||
@ -61,7 +76,7 @@ public abstract class Downloader {
 | 
			
		||||
 | 
			
		||||
    protected abstract int totalDownloadSize();
 | 
			
		||||
 | 
			
		||||
    public void download() throws IOException {
 | 
			
		||||
    protected void download() throws IOException {
 | 
			
		||||
        setupProgressListener();
 | 
			
		||||
        InputStream input = null;
 | 
			
		||||
        try {
 | 
			
		||||
 | 
			
		||||
@ -24,6 +24,13 @@ public class HttpDownloader extends Downloader {
 | 
			
		||||
        sourceUrl = new URL(source);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // The context is required for opening the file to write to.
 | 
			
		||||
    public HttpDownloader(String source, File destFile)
 | 
			
		||||
            throws FileNotFoundException, MalformedURLException {
 | 
			
		||||
        super(destFile);
 | 
			
		||||
        sourceUrl = new URL(source);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Downloads to a temporary file, which *you must delete yourself when
 | 
			
		||||
     * you are done*.
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user