Android 文件下载

来源:互联网 发布:百度文库离线文件json 编辑:程序博客网 时间:2024/05/17 23:44

1.使用 AsyncHttpClient 开源框架

 AsyncHttpClient 开源框架可以使我们轻松地获取网络数据或者向服务器发送数据,最关键的是,它是异步框架,在底层使用线程池处理并发请求,效率很高,使用又特别简单。

    以往我们在安卓上做项目,比如要下载很多图片、网页或者其他的资源,多数开发者会选择一个线程一个下载任务这种模型,因为安卓自带的 AndroidHttpClient 或者 java 带的 java.net.URL ,默认都是阻塞式操作。这种模型效率不高,对并发要求高的 APP 来讲,并不适用。有的人会选择使用 nio 自己实现,代码复杂度又很高。

    AsyncHttpClient 作为 android-async-http 框架的一个核心应用类,使用简单,可以处理文本、二进制等各种格式的 web 资源。下面提供一些代码来看如何使用:


public class Downloader {    public static AsyncHttpClient mHttpc = new AsyncHttpClient();    public static String TAG = "Downloader";    public void downloadText(String uri){        mHttpc.get(uri, null, new AsyncHttpResponseHandler(){@Overridepublic void onFailure(int arg0, Header[] arg1, byte[] arg2,Throwable arg3) {Log.i(TAG, "download failed.");}@Overridepublic void onSuccess(int arg0, Header[] arg1, byte[] arg2) {Log.i(TAG, "downloaded, thread id " + Thread.currentThread().getId());}        });    }        public void downloadImage(String uri, String savePath){        mHttpc.get(uri, new ImageResponseHandler(savePath));    }    public class ImageResponseHandler extends BinaryHttpResponseHandler{        private String mSavePath;            public ImageResponseHandler(String savePath){            super();            mSavePath = savePath;        }@Overridepublic void onFailure(int arg0, Header[] arg1, byte[] arg2,Throwable arg3) {Log.i(TAG, "download failed");}@Overridepublic void onSuccess(int arg0, Header[] arg1, byte[] arg2) {Log.i(TAG, "download image, file length " + arg2.length);}    }};

    上面的代码演示了如何使用 AsyncHttpResponseHandler 和 BinaryHttpResponseHandler ,相信 AsyncHttpClient  会给大家带来很大的便利。

2.使用xUtils开源框架

public class XutilsDownloader {public static void download(final Context context,String url,final String target){HttpUtils http=new HttpUtils();http.download(url, target,true,new RequestCallBack<File>() {@Overridepublic void onSuccess(ResponseInfo<File> arg0) {Toast.makeText(context, "文件下载完成,保存在:"+target, 0).show();}@Overridepublic void onFailure(HttpException arg0, String arg1) {Toast.makeText(context, "文件下载失败,网络异常", 0).show();}});}}

3.自己实现线程下载

public class MulThreadDownloader implements Runnable{private int threadCount=3;//默认使用三个线程下载private String path;public MulThreadDownloader(int _threadCount,String path){this.threadCount=_threadCount;this.path=path;}@Overridepublic void run() {URL url;try {url = new URL(path);HttpURLConnection conn = (HttpURLConnection) url.openConnection();conn.setRequestMethod("GET");conn.setConnectTimeout(3000);int code = conn.getResponseCode();if (200 == code) {int length = conn.getContentLength();RandomAccessFile raf = new RandomAccessFile(Environment.getExternalStorageDirectory()+"/temp.exe", "rw");raf.setLength(length);//计算每个子线程下载数据块大小:int blockSize = length / threadCount;for (int threadId = 0; threadId < threadCount; threadId++) {// blocksize=length/threadCount:10/3=3// 确定每个子线程下载数据的起始位置和结束位置:// 第0个线程:开始位置 0*3=0 结束位置:(0+1)*3-1// 第1个线程:开始位置 1*3=3 结束位置:(1+1)*3-1// ...// 第n个线程:开始位置 n*blocksize 结束位置:(n+1)*blocksize-1// n是线程的id// 最后一个子线程下载的结束位置:length-1int startIndex = threadId * blockSize;int endIndex = (threadId + 1) * blockSize - 1;if (threadId == (threadCount - 1)) {endIndex = length - 1;}// 创建子线程,下载对应数据块:new ChildThreadDownLoader(threadId,startIndex,endIndex,path).start();}}} catch (Exception e) {e.printStackTrace();}}}class ChildThreadDownLoader extends Thread{private int threadId;private int startIndex;private int endIndex;private String path;private  static int runningThreadCount = 3;public ChildThreadDownLoader(int threadId, int startIndex, int endIndex,String path) {super();this.threadId = threadId;this.startIndex = startIndex;this.endIndex = endIndex;this.path = path;}@Overridepublic void run() {try {URL url = new URL(path);HttpURLConnection conn = (HttpURLConnection) url.openConnection();conn.setRequestMethod("GET");conn.setConnectTimeout(3000);//告诉服务器子线程请求的数据范围conn.setRequestProperty("Range", "bytes="+startIndex+"-"+endIndex);//请求部分数据成功返回的响应码是206int code = conn.getResponseCode();if(206 == code){InputStream is = conn.getInputStream();RandomAccessFile raf = new RandomAccessFile(Environment.getExternalStorageDirectory()+"/temp.exe","rwd");raf.seek(startIndex);System.out.println("线程"+threadId+"正在下载..................."); byte[] buffer = new byte[1024*1024]; int len = 0;while((len = is.read(buffer)) != -1){raf.write(buffer, 0, len);}is.close();raf.close();}System.out.println("线程"+threadId+"下载完毕...................");//确定每个子线程什么下载完毕synchronized (ChildThreadDownLoader.class) {runningThreadCount --;if(runningThreadCount == 0){System.out.println("文件下载完成..............");}}} catch (Exception e) {e.printStackTrace();}}}


0 0
原创粉丝点击