1.下载类
package com.young.download.factory;import java.io.BufferedInputStream;import java.io.File;import java.io.IOException;import java.io.RandomAccessFile;import java.net.URL;import java.net.URLConnection;import android.util.Log;/** *  * 文件下载类 *  */public class FileDownloadThread extends Thread {private static final String TAG = "FileDownloadThread";/** 缓冲区 */private static final int BUFF_SIZE = 1024;/** 需要下载的URL */private URL url;/** 缓存的FIle */private File file;/** 开始位置 */private int startPosition;/** 结束位置 */private int endPosition;/** 当前位置 */private int curPosition;/** 完成 */private boolean finished = false;/** 已经下载多少 */private int downloadSize = 0;/*** * 分块文件下载,可以创建多线程模式 *  * @param url *            下载的URL * @param file *            下载的文件 * @param startPosition *            开始位置 * @param endPosition *            结束位置 */public FileDownloadThread(URL url, File file, int startPosition,int endPosition) {this.url = url;this.file = file;this.startPosition = startPosition;this.curPosition = startPosition;this.endPosition = endPosition;Log.e(TAG, toString());}@Overridepublic void run() {BufferedInputStream bis = null;RandomAccessFile rAccessFile = null;byte[] buf = new byte[BUFF_SIZE];URLConnection conn = null;try {conn = url.openConnection();conn.setConnectTimeout(10000);// 设置超时conn.setReadTimeout(10000);conn.setAllowUserInteraction(true);System.out.println(this.getName() + " startPosition "+ startPosition + " endPosition " + endPosition);// 根据范围下载数据conn.setRequestProperty("Range", "bytes=" + (startPosition) + "-"+ endPosition);// 读写rAccessFile = new RandomAccessFile(file, "rwd");// 从某个地方开始写入数据rAccessFile.seek(startPosition);bis = new BufferedInputStream(conn.getInputStream(), BUFF_SIZE);// 当前位置小于结束位置 继续下载while (curPosition < endPosition) {int len = bis.read(buf, 0, BUFF_SIZE);// 下载完成if (len == -1) {break;}rAccessFile.write(buf, 0, len);curPosition = curPosition + len;// 如果下载多了,则减去多余部分if (curPosition > endPosition) { System.out.println("  curPosition > endPosition  !!!!");int extraLen = curPosition - endPosition;downloadSize += (len - extraLen + 1);} else {downloadSize += len;}}this.finished = true; // 当前阶段下载完成Log.e(TAG, "当前" + this.getName() + "下载完成");} catch (Exception e) {Log.e(TAG, "download error Exception " + e.getMessage());e.printStackTrace();} finally {try {// 关闭流bis.close();rAccessFile.close();} catch (IOException e) {Log.e("AccessFile", "AccessFile IOException " + e.getMessage());}}super.run();}/** * 是否完成当前段下载完成 *  * @return */public boolean isFinished() {return finished;}/** * 已经下载多少 *  * @return */public int getDownloadSize() {return downloadSize;}@Overridepublic String toString() {return "FileDownloadThread [url=" + url + ", file=" + file+ ", startPosition=" + startPosition + ", endPosition="+ endPosition + ", curPosition=" + curPosition + ", finished="+ finished + ", downloadSize=" + downloadSize + "]";}}


2.更新信息处理类
package com.young.download.factory;import java.io.File;import java.io.RandomAccessFile;import java.net.URL;import java.net.URLConnection;import android.os.Handler;import android.os.Message;import android.util.Log;import com.young.download.util.FileUtil;/** * 多线程下载,UI更新类 *  **/public class MultiThreadDownload extends Thread {private static final String TAG = "MultiThreadDownload";/** 每一个线程需要下载的大小 */private int blockSize;/*** * 线程数量<br> * 默认为5个线程下载 */private int threadNum = 2;/*** 文件大小 */private int fileSize;/** * 已经下载多少 */private int downloadSize;/** 文件的url,线程编号,文件名称 */private String UrlStr, ThreadNo, fileName;/*** 保存的路径 */private String savePath;/** 下载的百分比 */private int downloadPercent = 0;/** 下载的 平均速度 */private int downloadSpeed = 0;/** 下载用的时间 */private int usedTime = 0;/** 当前时间 */private long curTime;/** 是否已经下载完成 */private boolean completed = false;private Handler handler;/** * 下载的构造函数 *  * @param url *            请求下载的URL * @param handler *            UI更新使用 * @param savePath *            保存文件的路径 */public MultiThreadDownload(Handler handler, String url, String savePath) {this.handler = handler;this.UrlStr = url;this.savePath = savePath;Log.e(TAG, toString());}@Overridepublic void run() {FileDownloadThread[] fds = new FileDownloadThread[threadNum];// 设置线程数量try {URL url = new URL(UrlStr);URLConnection conn = url.openConnection();fileSize = conn.getContentLength();this.fileName = FileUtil.getFileName(UrlStr);// 只创建一个文件,saveFile下载内容File saveFile = new File(savePath + "/" + fileName);Log.e(TAG, "文件一共:" + fileSize + " savePath " + savePath+ "  fileName  " + fileName);// 下载的文件内容RandomAccessFile accessFile = new RandomAccessFile(saveFile, "rwd");// 设置本地文件的长度和下载文件相同accessFile.setLength(fileSize);accessFile.close();// Handler更新UI,发送消息sendMsg(FileUtil.startDownloadMeg);// 每个线程下载的数据量blockSize = ((fileSize % threadNum) == 0) ? (fileSize / threadNum): (fileSize / threadNum + 1);Log.e(TAG, "每个线程分别下载 :" + blockSize);for (int i = 0; i < threadNum; i++) {int curThreadEndPosition = (i + 1) != threadNum ? ((i + 1)* blockSize - 1) : fileSize;FileDownloadThread fdt = new FileDownloadThread(url, saveFile,i * blockSize, curThreadEndPosition);fdt.setName("thread" + i);fdt.start();fds[i] = fdt;}/** * 获取数据,更新UI,直到所有下载线程都下载完成。 */boolean finished = false;// 开始时间,放在循环外,求解的usedTime就是总时间long startTime = System.currentTimeMillis();while (!finished) {downloadSize = 0;finished = true;for (int i = 0; i < fds.length; i++) {downloadSize += fds[i].getDownloadSize();if (!fds[i].isFinished()) {finished = false;}}downloadPercent = (downloadSize * 100) / fileSize;curTime = System.currentTimeMillis();System.out.println("curTime = " + curTime + " downloadSize = "+ downloadSize + " usedTime "+ (int) ((curTime - startTime) / 1000));usedTime = (int) ((curTime - startTime) / 1000);if (usedTime == 0)usedTime = 1;downloadSpeed = (downloadSize / usedTime) / 1024;sleep(1000);/* 1秒钟刷新一次界面 */sendMsg(FileUtil.updateDownloadMeg);}Log.e(TAG, "下载完成");completed = true;sendMsg(FileUtil.endDownloadMeg);} catch (Exception e) {Log.e(TAG, "multi file error  Exception  " + e.getMessage());e.printStackTrace();}super.run();}/** * 得到文件的大小 *  * @return */public int getFileSize() {return this.fileSize;}/** * 得到已经下载的数量 *  * @return */public int getDownloadSize() {return this.downloadSize;}/** * 获取下载百分比 *  * @return */public int getDownloadPercent() {return this.downloadPercent;}/** * 获取下载速度 *  * @return */public int getDownloadSpeed() {return this.downloadSpeed;}/** * 修改默认线程数 *  * @param threadNum */public void setThreadNum(int threadNum) {this.threadNum = threadNum;}/** * 分块下载完成的标志 *  * @return */public boolean isCompleted() {return this.completed;}@Overridepublic String toString() {return "MultiThreadDownload [threadNum=" + threadNum + ", fileSize="+ fileSize + ", UrlStr=" + UrlStr + ", ThreadNo=" + ThreadNo+ ", savePath=" + savePath + "]";}/** * 发送消息,用户提示 * */private void sendMsg(int what) {Message msg = new Message();msg.what = what;handler.sendMessage(msg);}}


3.Activity类
package com.young.download;import java.io.File;import android.app.Activity;import android.content.Intent;import android.net.Uri;import android.os.Bundle;import android.os.Environment;import android.os.Handler;import android.os.Message;import android.util.Log;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.ProgressBar;import android.widget.Toast;import com.young.download.factory.MultiThreadDownload;import com.young.download.util.FileUtil;public class MainActivity extends Activity implements OnClickListener {protected static final String TAG = "MainActivity";private Button button;private ProgressBar pb;// 需要下载的文件private String url = "http://gdown.baidu.com/data/wisegame/3c00add7144d3915/kugouyinle.apk";private MultiThreadDownload mUpdateUIThread = null;@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main);button = (Button) this.findViewById(R.id.button);button.setOnClickListener(this);pb = (ProgressBar) this.findViewById(R.id.pb);mUpdateUIThread = new MultiThreadDownload(handler, url,FileUtil.setMkdir(this) + File.separator);}@Overridepublic void onClick(View v) {mUpdateUIThread.start();}// 对返回的数据进行处理private Handler handler = new Handler() {@Overridepublic void handleMessage(Message msg) {switch (msg.what) {case FileUtil.startDownloadMeg:// 设置进度条中最大的值是文件的大小pb.setMax(mUpdateUIThread.getFileSize()); break;case FileUtil.updateDownloadMeg:if (!mUpdateUIThread.isCompleted()) // 下载{Log.e(TAG, "已下载:" + mUpdateUIThread.getDownloadSize());pb.setProgress(mUpdateUIThread.getDownloadSize());button.setText("下载速度:" + mUpdateUIThread.getDownloadSpeed()+ "k/秒       下载百分比"+ mUpdateUIThread.getDownloadPercent() + "%");} else {button.setText("下载完成");}break;case FileUtil.endDownloadMeg:Toast.makeText(MainActivity.this, "下载完成,马上安装",Toast.LENGTH_SHORT).show();// 对下载的APK文件进行安装String filename = FileUtil.getFileName(url);String str = "/myfile/" + filename;// 文件的全路径String fileName = Environment.getExternalStorageDirectory()+ str;Intent intent = new Intent(Intent.ACTION_VIEW);// 设置intent的data和Type属性。 intent.setDataAndType(Uri.fromFile(new File(fileName)),"application/vnd.android.package-archive");// 跳转到安装页面startActivity(intent);break;}super.handleMessage(msg);}};}









更多相关文章

  1. android ant
  2. 使用HttpURLConnection请求数据、上传文件、图片等
  3. android_service_totoal
  4. Android中的数据库操作(保证线程安全)
  5. android计时器 message+handler; timer+timertask
  6. Android中Assets下文件操作
  7. Android中关于路径
  8. android 断点下载---XUtils
  9. Service入门(一)——startService、stopService

随机推荐

  1. Android ViewPager嵌套ViewPager+Fragmen
  2. android webview快速获取页面上的图片
  3. 【简单的学生管理界面】Android的if语句
  4. Android shape中的padding无效
  5. Android代码混淆只需简单三步
  6. Android(安卓)通讯录学习笔记之——目标:
  7. android官方技术文档翻译——工具属性
  8. 穿针引线,帮你回忆, 汇总:Android系统启动流
  9. Android opencv(三) 边缘检测Sobel、Cann
  10. WindowsPhone下拉刷新控件 - PullRefresh