码迷,mamicode.com
首页 > 其他好文 > 详细

F-droid 源码片段(二)下载模块整理

时间:2014-09-26 20:57:18      阅读:203      评论:0      收藏:0      [点我收藏+]

标签:f-droid   下载   

 这篇文章把F-droid的下载功能经过修改单独拿出来,而且做了一个demo。

希望能对自己后续起到借鉴作用。各位童鞋也可以去进行下载。

 

其实主要的思想有2个

 

1、使用接口进行回调

2、线程直接调用回调,由于无法知道主线程是否进行UI操作,所以把线程的回调进行了包装,使用Handler来发消息。保证不会崩溃。

 

 

项目下载地址:

http://download.csdn.net/download/leehu1987/7979253

 

一、定义一个接口,用于页面下载状态的监听;

<pre class="java" name="code">import java.io.Serializable;

public interface DownloadListener {

	public static class Data implements Serializable {
		private static final long serialVersionUID = 8954447444334039739L;
		private long currentSize;
		private long totalSize;

		public Data() {
		}

		public Data(int currentSize, int totalSize) {
			this.currentSize = currentSize;
			this.totalSize = totalSize;
		}

		public long getCurrentSize() {
			return currentSize;
		}

		public void setCurrentSize(long currentSize) {
			this.currentSize = currentSize;
		}

		public long getTotalSize() {
			return totalSize;
		}

		public void setTotalSize(long totalSize) {
			this.totalSize = totalSize;
		}

		@Override
		public String toString() {
			return "Data [currentSize=" + currentSize + ", totalSize="
					+ totalSize + "]";
		}

	}

	/**
	 * 
	 * @param data
	 *            : transfer downloaded data
	 */
	public void onProgress(Data data);

	/**
	 * 
	 * @param e
	 *            : exception
	 */
	public void onError(Exception e);

	public void onCompleted();
}

 

二、定义了一个Downloader父类,为了适应不同的下载,比如使用Http进行下载;使用代理进行下载等。

所以这个类是一个接口类,定义了一些基本的操作方法。

 

package com.example.downloader;

package com.example.downloader;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.MalformedURLException;
import java.net.URL;

import android.util.Log;

public abstract class Downloader {
	private static final String TAG = "Downloader";
	protected URL sourceUrl;
	private OutputStream outputStream;
	private DownloadListener downloadListener = null;
	private File outputFile;
	private final int BUFFER_SIZE = 1240000;//1M

	// ///////////////////////////
	public abstract InputStream getInputStream() throws IOException;

	public abstract int totalDownloadSize();

	public abstract void download() throws IOException, InterruptedException;

	// ///////////////////////////

	Downloader(File destFile) throws FileNotFoundException,
			MalformedURLException {
		outputFile = destFile;
		outputStream = new FileOutputStream(outputFile);
	}

	public void setProgressListener(DownloadListener downloadListener) {
		this.downloadListener = downloadListener;
	}

	public File getFile() {
		return outputFile;
	}

	protected void downloadFromStream() throws IOException,
			InterruptedException {
		Log.d(TAG, "Downloading from stream");
		InputStream input = null;
		try {
			input = getInputStream();
			throwExceptionIfInterrupted();
			copyInputToOutputStream(getInputStream());
		} finally {
			try {
				if (outputStream != null) {
					outputStream.close();
				}
				if (input != null) {
					input.close();
				}
			} catch (IOException ioe) {
				// ignore
			}
		}
		// Even if we have completely downloaded the file, we should probably
		// respect
		// the wishes of the user who wanted to cancel us.
		throwExceptionIfInterrupted();
	}

	/**
	 * stop thread
	 * 
	 * @throws InterruptedException
	 */
	private void throwExceptionIfInterrupted() throws InterruptedException {
		if (Thread.interrupted()) {
			Log.d(TAG, "Received interrupt, cancelling download");
			throw new InterruptedException();
		}
	}

	protected void copyInputToOutputStream(InputStream input)
			throws IOException, InterruptedException {

		byte[] buffer = new byte[BUFFER_SIZE];
		int bytesRead = 0;
		int totalBytes = totalDownloadSize();
		throwExceptionIfInterrupted();
		sendProgress(bytesRead, totalBytes);
		while (true) {
			int count = input.read(buffer);
			throwExceptionIfInterrupted();
			bytesRead += count;
			sendProgress(bytesRead, totalBytes);
			if (count == -1) {
				Log.d(TAG, "Finished downloading from stream");
				break;
			}
			outputStream.write(buffer, 0, count);
		}
		outputStream.flush();
	}

	protected void sendProgress(int bytesRead, int totalBytes) {
		if (downloadListener != null) {
			DownloadListener.Data data = new DownloadListener.Data(bytesRead,
					totalBytes);
			downloadListener.onProgress(data);
		}
	}
}

 

三、写了一个HttpDownloader。继承自Downloader

package com.example.downloader;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

public class HttpDownloader extends Downloader {

	protected HttpURLConnection connection;

	HttpDownloader(String source, File destFile) throws FileNotFoundException,
			MalformedURLException {
		super(destFile);
		sourceUrl = new URL(source);
	}

	@Override
	public void download() throws IOException, InterruptedException {
		setupConnection();
		downloadFromStream();
	}

	protected void setupConnection() throws IOException {
		if (connection != null) {
			return;
		}
		connection = (HttpURLConnection) sourceUrl.openConnection();
	}

	@Override
    public InputStream getInputStream() throws IOException {
        setupConnection();
        return connection.getInputStream();
    }

	@Override
    public int totalDownloadSize() {
        return connection.getContentLength();
    }

}



 四、需要一个控制方法

 

package com.example.downloader;

import java.io.IOException;

import com.example.downloader.DownloadListener.Data;

import android.os.Handler;
import android.os.Message;
import android.util.Log;

public class DownloadManager extends Handler {

	private DownloadThread downloadThread;
	private Downloader downloader;
	private DownloadListener listener;

	private static final int MSG_PROGRESS = 1;
	private static final int MSG_DOWNLOAD_COMPLETE = 2;
	private static final int MSG_DOWNLOAD_CANCELLED = 3;
	private static final int MSG_ERROR = 4;

	public DownloadManager(Downloader downloader, DownloadListener listener) {
		this.downloader = downloader;
		this.listener = listener;
	}

	@Override
	public void handleMessage(Message msg) {
		super.handleMessage(msg);
		switch (msg.what) {
		case MSG_PROGRESS: {
			DownloadListener.Data data = (Data) msg.obj;
			if (listener != null) {
				listener.onProgress(data);
			}
			break;
		}
		case MSG_DOWNLOAD_COMPLETE: {
			if (listener != null) {
				listener.onCompleted();
			}
			break;
		}
		case MSG_DOWNLOAD_CANCELLED: {
			break;
		}
		case MSG_ERROR: {
			Exception e = (Exception) msg.obj;
			if (listener != null) {
				listener.onError(e);
			}
			break;
		}
		default:
			return;
		}
	}

	public void download() {
		downloadThread = new DownloadThread();
		downloadThread.start();
	}

	private class DownloadThread extends Thread implements<strong><span style="color:#ff6666;"> DownloadListener </span></strong>{

		private static final String TAG = "DownloadThread";

		public void run() {
			try {
				downloader.setProgressListener(this);
				downloader.download();
				sendMessage(MSG_DOWNLOAD_COMPLETE);
			} catch (InterruptedException e) {
				sendMessage(MSG_DOWNLOAD_CANCELLED);
			} catch (IOException e) {
				Log.e(TAG, e.getMessage() + ": " + Log.getStackTraceString(e));
				Message message = new Message();
				message.what = MSG_ERROR;
				message.obj = e;
				sendMessage(message);
			}
		}

		private void sendMessage(int messageType) {
			Message message = new Message();
			message.what = messageType;
			DownloadManager.this.sendMessage(message);
		}

		private void sendMessage(Message msg){
			DownloadManager.this.sendMessage(msg);
		}
		@Override
		public void onProgress(Data data) {
			// TODO
			Message message = new Message();
			message.what = MSG_PROGRESS;
			message.obj =data;
			DownloadManager.this.sendMessage(message);
		}

		@Override
		public void onError(Exception e) {
			// 在这里没有任何用,异常被捕获了
			// do nothing
		}

		@Override
		public void onCompleted() {
			// do nothing
		}
	}
}


五、页面如何使用

<pre class="html" name="code">package com.example.downloader;

import java.io.File;
import java.io.FileNotFoundException;
import java.net.MalformedURLException;

import android.os.Bundle;
import android.os.Environment;
import android.app.Activity;
import android.view.Menu;

public class MainActivity extends Activity implements DownloadListener {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		String dir = Environment.getExternalStorageDirectory()
				.getAbsolutePath() + File.separator + "test.apk";
		File f = new File(dir);
		try {
			Downloader downloader = new HttpDownloader(
					"http://192.168.131.63/fengxing2.2.0.6.apk", f);
			DownloadManager m = new DownloadManager(downloader, this);
			m.download();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (MalformedURLException e) {
			e.printStackTrace();
		}
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

	@Override
	public void onProgress(Data data) {
		System.out.println("======"+data);
		
	}

	@Override
	public void onError(Exception e) {
		System.out.println("======");
		e.printStackTrace();
		
	}

	@Override
	public void onCompleted() {
		System.out.println("======下载完成");
		
	}

}



尚未完成的功能:

1、断点下载(需要数据库)

2、如果下载完成了,下次下载应该是不需要下载了。

 

F-droid 源码片段(二)下载模块整理

标签:f-droid   下载   

原文地址:http://blog.csdn.net/leehu1987/article/details/39583497

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!