安卓开发-多线程常规实现+xUtils-master开源框架实现 断点下载
2017-09-17 14:38
477 查看
《方式一:多线程下载之常规实现》
原理如图:
1.创建url
2.打开链接
3.判断相应码是否为200(没有设置请求头为200)
4.得到要下载资源的长度(4.5.6.7在if中)
5.利用RandomAccessFile在files文件中创建和将要下载文件一样容量的空文件
6.计算出每个线程负责下载文件的大小
7.对每个线程的任务做迭代下载
8.创建下载资源线程类:
9.完整代码:
10.RandomAccessFile的功能总结:
《方式二:xUtils-master开源框架实现断点下载》
1.引入框架,如图:
2.创建一个下载按钮,为其设置下载点击事件:
原理如图:
1.创建url
URL url = new URL(getUrl()); //下载来自tomcat下的webapps/ROOT/resource.rar文件,10.0.2.2是安卓映射的服务器的地址,此时不再是localhost或者是本机ip private String getUrl(){ return "http://10.0.2.2:8080/resource.rar"; }
2.打开链接
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
3.判断相应码是否为200(没有设置请求头为200)
if(conn.getResponseCode() == 200){
4.得到要下载资源的长度(4.5.6.7在if中)
int contentLength = conn.getContentLength();
5.利用RandomAccessFile在files文件中创建和将要下载文件一样容量的空文件
File file = new File(getFilesDir(), getFileName(getUrl())); //设置文件权限为可读可写 RandomAccessFile raf = new RandomAccessFile(file, "rw"); raf.setLength(contentLength);//定义空文件长度
6.计算出每个线程负责下载文件的大小
//MAX_THREAD_NUM为全局变量,设定资源分给几个线程下载 int preThreadLength = contentLength/MAX_THREAD_NUM;
7.对每个线程的任务做迭代下载
for (int i = 0; i < MAX_THREAD_NUM; i++) { int startIndex = i * preThreadLength;//线程下载的起始点 int endIndex = (i + 1) * preThreadLength - 1;//线程下载的结束点 if(i == MAX_THREAD_NUM - 1){ endIndex = contentLength - 1; } //每次从新开启一个新的线程下载,i可用来判断是否下载完毕 new DownLoadFile(i, startIndex, endIndex).start(); }
8.创建下载资源线程类:
8.1.创建全局变量:
private int mCurrentThreadNum;//当前线程号(默认从0开始) private int mStartIndex;//当前线程下载的起始点 private int mEndIndex;//当前线程下载的结束点 private int mLastIndex;//上次下载断点位置
8.2.创建构造器:
public DownLoadFile(int currentThreadNum, int firstIndex, int endIndex){ mCurrentThreadNum = currentThreadNum; mStartIndex = firstIndex; mEndIndex = endIndex; mLastIndex = firstIndex; }
8.3:重写Thread中的run方法:
public void run() { try { //1.创建url URL url = new URL(getUrl()); //2.打开链接 HttpURLConnection conn = (HttpURLConnection) url.openConnection(); //3.得到files中的断点文件信息,并将值赋给mLastIndex File file = getRecoredFile(mCurrentThreadNum, getFileName(getUrl())); if(file.exists()){ InputStream is = new FileInputStream(file); BufferedReader reader = new BufferedReader(new InputStreamReader(is)); mLastIndex = Integer.valueOf(reader.readLine()); } //4.设置请求头信息,如果是第一次,就用mStartIndex(下载相关:Range : bytes=起始点-结束点) conn.setRequestProperty("Range", "bytes=" +( mLastIndex != 0 ? mLastIndex : mStartIndex )+ "-" + mEndIndex); //5.判断相应码是否为206,设置下载的请求头后响应码不再是200 if(conn.getResponseCode() == 206){ //6.获取输入流 InputStream is = conn.getInputStream(); //7.利用RandomAccessFile得到在file下创建好的文件 File files = new File(getFilesDir(), getFileName(getUrl())); RandomAccessFile raf = new RandomAccessFile(files, "rw"); raf.skipBytes(mLastIndex);//跳过多少个字节 //8.向文件中写数据 byte[] buffer = new byte[1024]; int readCount; while((readCount = is.read(buffer)) != -1){ mLastIndex += readCount; raf.write(buffer, 0, readCount); //9.根据当前线程数和下载的资源名创建断点位置信息文件,并把数据写入 File recordFile = getRecoredFile(mCurrentThreadNum, getFileName(getUrl()) ); RandomAccessFile recordRaf = new RandomAccessFile(recordFile, "rws"); recordRaf.write((mLastIndex + "").getBytes()); //10,为进度条设置max和Progress值 SeekBar sb = (SeekBar) mPbContainerLl.getChildAt(mCurrentThreadNum); sb.setMax(mEndIndex - mStartIndex); sb.setProgress(mLastIndex); } //11.下载完成后将断点位置文件删除 for (int i = 0; i < MAX_THREAD_NUM; i++) { getRecoredFile(mCurrentThreadNum, getFileName(getUrl())).delete(); } //12.下载完成的提示 if(mCurrentThreadNum == MAX_THREAD_NUM - 1){ Log.v("520it", "下載完成"); runOnUiThread(new Runnable() { @Override public void run() { Toast.makeText(MainActivity.this, "下載完成!", Toast.LENGTH_SHORT).show(); } }); } } } catch (Exception e) { e.printStackTrace(); } } //根据当前线程数和下载的资源名创建断点位置信息文件 private File getRecoredFile(int currentThreadNum, String fileName) { String recordFileName = fileName.substring(0, fileName.lastIndexOf(".")) + "#" + currentThreadNum + ".txt"; return new File(getFilesDir(),recordFileName); }
9.完整代码:
package com.m520it.downloadofmultithreadpoint;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.URL;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.SeekBar;
import android.widget.Toast;
public class MainActivity extends Activity {
private int MAX_THREAD_NUM = 3;
private LinearLayout mPbContainerLl;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mPbContainerLl = (LinearLayout) findViewById(R.id.pbContainer_ll);
}
public void downLoadOnClick(View v){
for (int i = 0; i < MAX_THREAD_NUM; i++) {
LayoutInflater inflater = LayoutInflater.from(this);
View view = inflater.inflate(R.layout.pbcontainer_layout, null);
mPbContainerLl.addView(view.findViewById(R.id.pb));
}
new Thread(){
public void run() {
try {
//1.创建url
URL url = new URL(getUrl());
//2.打开链接
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
//3.判断相应码是否为200(没有设置请求头为200)
if(conn.getResponseCode() == 200){
//4.得到文件的长度
int contentLength = conn.getContentLength();
//5.利用RandomAccessFile在files文件中创建和将要下载文件一样容量的空文件
File file = new File(getFilesDir(), getFileName(getUrl()));
RandomAccessFile raf = new RandomAccessFile(file, "rw");//设置文件权限为可读可写
raf.setLength(contentLength);//定义空文件长度
//6.计算出每个线程负责下载文件的大小
int preThreadLength = contentLength/MAX_THREAD_NUM;
//7.对每个线程的任务做迭代下载
for (int i = 0; i < MAX_THREAD_NUM; i++) {
int startIndex = i * preThreadLength;//线程下载的起始点
int endIndex = (i + 1) * preThreadLength - 1;//线程下载的结束点,最后一个线程负责下载其他线程剩下的所有任务
if(i == MAX_THREAD_NUM - 1){
endIndex = contentLength - 1;
}
Log.v("520it", "startup=" + startIndex + " endIndex=" + endIndex);
new DownLoadFile(i, startIndex, endIndex).start();//每次从新开启一个新的线程下载,i可用来判断是否下载完毕
}
}
} catch (Exception e) {
e.printStackTrace();
}
};
}.start();
}
class DownLoadFile extends Thread{
private int mCurrentThreadNum;//当前线程号(默认从0开始) private int mStartIndex;//当前线程下载的起始点 private int mEndIndex;//当前线程下载的结束点 private int mLastIndex;//上次下载断点位置
public DownLoadFile(int currentThreadNum, int firstIndex, int endIndex){ mCurrentThreadNum = currentThreadNum; mStartIndex = firstIndex; mEndIndex = endIndex; mLastIndex = firstIndex; }
public void run() {
try {
//1.创建url
URL url = new URL(getUrl());
//2.打开链接
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
//3.得到files中的断点文件信息,并将值赋给mLastIndex
File file = getRecoredFile(mCurrentThreadNum, getFileName(getUrl()));
if(file.exists()){
InputStream is = new FileInputStream(file);
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
mLastIndex = Integer.valueOf(reader.readLine());
}
//4.设置请求头信息,如果是第一次,就用mStartIndex(下载相关:Range : bytes=起始点-结束点)
conn.setRequestProperty("Range", "bytes=" +( mLastIndex != 0 ? mLastIndex : mStartIndex )+ "-" + mEndIndex);
//5.判断相应码是否为206,设置下载的请求头后响应码不再是200
if(conn.getResponseCode() == 206){
//6.获取输入流
InputStream is = conn.getInputStream();
//7.利用RandomAccessFile得到在file下创建好的文件
File files = new File(getFilesDir(), getFileName(getUrl()));
RandomAccessFile raf = new RandomAccessFile(files, "rw");
raf.skipBytes(mLastIndex);//跳过多少个字节
//8.向文件中写数据
byte[] buffer = new byte[1024];
int readCount;
while((readCount = is.read(buffer)) != -1){
mLastIndex += readCount;
raf.write(buffer, 0, readCount);
//9.根据当前线程数和下载的资源名创建断点位置信息文件,并把
File recordFile = getRecoredFile(mCurrentThreadNum, getFileName(getUrl()) );
RandomAccessFile recordRaf = new RandomAccessFile(recordFile, "rws");
recordRaf.write((mLastIndex + "").getBytes());
//为进度条设置max和Progress值
SeekBar sb = (SeekBar) mPbContainerLl.getChildAt(mCurrentThreadNum);
sb.setMax(mEndIndex - mStartIndex);
sb.setProgress(mLastIndex);
}
//下载完成后将断点位置文件删除
for (int i = 0; i < MAX_THREAD_NUM; i++) {
getRecoredFile(mCurrentThreadNum, getFileName(getUrl())).delete();
}
//下载完成的提示
if(mCurrentThreadNum == MAX_THREAD_NUM - 1){
Log.v("520it", "下載完成");
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(MainActivity.this, "下載完成!", Toast.LENGTH_SHORT).show();
}
});
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
private File getRecoredFile(int currentThreadNum,
String fileName) {
String recordFileName = fileName.substring(0, fileName.lastIndexOf(".")) + "#" + currentThreadNum + ".txt";
return new File(getFilesDir(),recordFileName);
}
}
private String getFileName(String url){
return url.substring(url.lastIndexOf("/") + 1);
}
private String getUrl(){
return "http://10.0.2.2:8080/resource.rar";
}
}
10.RandomAccessFile的功能总结:
10.1:在指定位置创建一个指定大小的空文件:
File file = new File(getFilesDir(), getFileName(getUrl())); //设置文件权限为可读可写 RandomAccessFile raf = new RandomAccessFile(file, "rw"); raf.setLength(contentLength);//定义空文件长度
10.2:可在指定文件内跳过指定个数的字节进行写入数据
File files = new File(getFilesDir(), getFileName(getUrl())); RandomAccessFile raf = new RandomAccessFile(files, "rw"); raf.skipBytes(mLastIndex);//跳过多少个字节 raf.write(buffer, 0, readCount);
《方式二:xUtils-master开源框架实现断点下载》
1.引入框架,如图:
2.创建一个下载按钮,为其设置下载点击事件:
public void downLoadClick(View v){ //1.创建httpUtils对象 HttpUtils httpUtils = new HttpUtils(); //创建资源文件保存位置文件 File file = new File(getFilesDir(), getFileName(getUrl())); //2.调用下载函数(资源路径,保存资源位置的绝对路径,是否支持断点下载,请求回调函数重写) httpUtils.download(getUrl(), file.getAbsolutePath(), true, new RequestCallBack<File>() { @Override public void onSuccess(ResponseInfo<File> responseInfo) { Toast.makeText(MainActivity.this, "下載完成", Toast.LENGTH_SHORT).show(); Log.v("520it", "下載完成"); } @Override public void onFailure(HttpException error, String msg) { // TODO Auto-generated method stub } }); }
相关文章推荐
- 安卓系统下的多线程断点下载实现2利用开源框架XUtils
- 使用开源项目xutils实现多线程断点下载
- 安卓开发之多线程断点下载(三)
- (开源多线程断点下载)开源项目xutils-
- 8 基于框架XUtils下的多线程断点下载
- iOS开发网络篇―实现大文件的多线程断点下载
- Android使用开源项目Xutils实现多线程下载文件
- 安卓应用程序插件化开发框架 -AAP Framework【开源项目】
- (Android小应用)在Android中实现多线程断点下载(连载二)
- (Android小应用)在Android中实现多线程断点下载(连载一)
- android实现多任务多线程支持断点下载的下载软件
- Java实现多线程断点下载
- android 多线程断点下载实现
- 多线程断点下载的实现
- ERP框架开发中的License许可验证机制设计与实现 (包含源代码下载)
- ERP框架开发中的License许可验证机制设计与实现 (包含源代码下载)
- 使用java实现http多线程断点下载文件(一)
- (Android小应用)在Android中实现多线程断点下载
- Asp.net(c#)实现多线程断点下载
- 使用java实现http多线程断点下载文件(二)