android多线程下载
2014-08-13 22:42
120 查看
------<a href="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! -------
package com.dream.multidownloader;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.URL;
import android.app.Activity;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import com.dream.multidownloader.DB.TempDataOpenHeandler;
public class MainActivity extends Activity {
protected static final int DOWNLOAD_ERROR = 1;
protected static final int SERVER_ERROR = 2;
public static final int DOWNLOAD_SUCCESS = 3;
public static final int CHANGE_TEXTPROCESS = 4;
private EditText et_path;
private ProgressBar pb; //进度条
private TextView tv_process;
private static int threadCount = 3;
private static int threadNum = threadCount; // 记录存活的线程
private static int currentProcess = 0; //当前已下载进度
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case DOWNLOAD_ERROR:
Toast.makeText(getApplicationContext(), "下载失败", 0).show();
break;
case CHANGE_TEXTPROCESS:
tv_process.setText("下载进度:"+pb.getProgress()*100/pb.getMax()+"%");
break;
case SERVER_ERROR:
Toast.makeText(getApplicationContext(), "服务器错误", 0).show();
break;
case DOWNLOAD_SUCCESS:
Toast.makeText(getApplicationContext(), "下载完成", 0).show();
break;
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
et_path = (EditText) findViewById(R.id.et_path);
pb = (ProgressBar) findViewById(R.id.pb);
tv_process = (TextView) findViewById(R.id.tv_process);
}
/**
* 点击下载事件
* @param view
*/
public void downLoad(View view) {
final String path = et_path.getText().toString().trim();
if (path != null && !"".equals(path)) {
new Thread() {
public void run() {
// String path = "http://localhost:8080/qvod.exe";
// String path = "http://localhost:8080/demo.txt";
// String path =
// "http://www.cnblogs.com/Googler/archive/2010/08/19/1803700.html";
try {
URL url = new URL(path);
HttpURLConnection conn = (HttpURLConnection) url
.openConnection();
conn.setConnectTimeout(5000);
conn.setRequestMethod("GET");
int code = conn.getResponseCode();
System.out.println("请求码:" + code);
if (code == 200) {
// 获取资源长度
int length = conn.getContentLength();
pb.setMax(length); //设置进度条最大值
System.out.println("文件长度为:" + length);
// 定义一个随机访问文件
// RandomAccessFile randomFile = new
// RandomAccessFile("demo.txt",
// "rwd");
RandomAccessFile randomFile = new RandomAccessFile(
"/sdcard/qvod.exe", "rwd");
randomFile.setLength(length);// 设置文件长度
randomFile.close();
// 计算每个线程下载的数据
int blockSize = length / threadCount;
for (int threadId = 1; threadId <= threadCount; threadId++) {
int startIndex = (threadId - 1) * blockSize;
int endIndex = (threadId == threadCount) ? length - 1
: threadId * blockSize - 1;
System.out
.println("线程" + threadId + "[ "
+ startIndex + "--->"
+ endIndex + " ]");
TempDataOpenHeandler tempData = new TempDataOpenHeandler(
MainActivity.this);
new DownloadThread(path, startIndex, endIndex,
threadId,tempData).start();
}
}
else {
System.out.println("服务器出现错误、、、");
Message msg = new Message();
msg.what = SERVER_ERROR;
handler.sendMessage(msg);
}
}
catch (Exception e) {
e.printStackTrace();
Message msg = new Message();
msg.what = DOWNLOAD_ERROR;
handler.sendMessage(msg);
}
};
}.start();
}
else {
Toast.makeText(this, "路径错误", 0).show();
return;
}
}
/**
* 多线程下载
*
* @author Dream
*
*/
private class DownloadThread extends Thread {
private String path; // 资源路径
private int startIndex; // 开始位置
private int endIndex; // 结束位置
private int threadId; // 线程号
private TempDataOpenHeandler tempData = null;
public DownloadThread(String path, int startIndex, int endIndex,
int threadId,TempDataOpenHeandler tempData) {
this.path = path;
this.startIndex = startIndex;
this.endIndex = endIndex;
this.threadId = threadId;
this.tempData = tempData;
}
@Override
public void run() {
SQLiteDatabase db = tempData.getWritableDatabase();
try {
Cursor cursor = db.query("tempInfo",
new String[] { "startIndex" }, "id=?",
new String[] { threadId+"" }, null, null, null);
if (cursor.moveToNext()) {
int realStartIndex = cursor.getInt(0);
currentProcess += realStartIndex - startIndex;
startIndex = realStartIndex;
// System.out.println("线程"+threadId+"的每次开始位置为"+startIndex+"--------------------------------");
}else{
ContentValues values = new ContentValues();
values.put("id", threadId);
values.put("startIndex", 0);
db.insert("tempInfo", null, values);
}
cursor.close();
db.close();
// // 获取断点的开始位置
// File tempFile = new File("/sdcard/"+threadId + ".txt");
// if (tempFile.exists() && tempFile.length() > 0) {
//
// FileInputStream tempIn = new FileInputStream(tempFile);
// int leng = 0;
// byte[] tempBuff = new byte[1024];
//
// int len = tempIn.read(tempBuff);
// int downLoadStart = Integer.parseInt(new String(tempBuff,
// 0, len));
// startIndex = downLoadStart;
// }
System.out.println("线程" + threadId + "真实开始位置:[ " + startIndex
+ "--->" + endIndex + " ]");
URL url = new URL(path);
HttpURLConnection conn = (HttpURLConnection) url
.openConnection();
conn.setConnectTimeout(5000);
conn.setRequestMethod("GET");
conn.setRequestProperty("Range", "bytes=" + startIndex + "-"
+ endIndex);
int code = conn.getResponseCode();// 注意此处如果请求全部的资源的返回200,部分资源返回206
System.out.println("code:" + code);
InputStream in = conn.getInputStream();
RandomAccessFile randomFile = new RandomAccessFile(
"/sdcard/qvod.exe", "rwd");
// RandomAccessFile randomFile = new
// RandomAccessFile("demo.txt", "rwd");
randomFile.seek(startIndex);// 设置文件开始位置
int total = 0;
int len = 0;
byte[] buff = new byte[1024];
while ((len = in.read(buff)) != -1) {
// RandomAccessFile info = new
// RandomAccessFile("/sdcard/"+threadId
// + ".txt", "rwd");
randomFile.write(buff, 0, buff.length);
total += len;
System.out.println("线程" + threadId + ":total=" + total);
db = tempData.getWritableDatabase();
db.execSQL("UPDATE tempInfo set startIndex = ? WHERE id = ?", new Object[]{total+startIndex,threadId});
db.close();
synchronized (MainActivity.this) {
currentProcess += len; //累计下载量
pb.setProgress(currentProcess); //设置下载进度
Message msg = Message.obtain(); //从消息池中取消息
msg.what = CHANGE_TEXTPROCESS;
handler.sendMessage(msg);
}
// info.write((total + startIndex + "").getBytes());
// info.close();
}
in.close();
randomFile.close();
}
catch (Exception e) {
e.printStackTrace();
}
finally {
// new File(threadId + ".txt").delete();
synchronized (MainActivity.this) {
threadNum--;
System.out.println("线程"+threadId+"下载完成!!!");
if (threadNum == 0) {
db = tempData.getWritableDatabase();
db.execSQL("DELETE FROM tempInfo");
db.close();
// for (int i = 1; i <= threadCount; i++) {
// new File("/sdcard/" + i + ".txt").delete();
// }
System.out.println("文件下载完成,删除所有临时文件");
Message msg = new Message();
msg.what = DOWNLOAD_SUCCESS;
handler.sendMessage(msg);
}
}
}
}
}
}
package com.dream.multidownloader;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.URL;
import android.app.Activity;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import com.dream.multidownloader.DB.TempDataOpenHeandler;
public class MainActivity extends Activity {
protected static final int DOWNLOAD_ERROR = 1;
protected static final int SERVER_ERROR = 2;
public static final int DOWNLOAD_SUCCESS = 3;
public static final int CHANGE_TEXTPROCESS = 4;
private EditText et_path;
private ProgressBar pb; //进度条
private TextView tv_process;
private static int threadCount = 3;
private static int threadNum = threadCount; // 记录存活的线程
private static int currentProcess = 0; //当前已下载进度
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case DOWNLOAD_ERROR:
Toast.makeText(getApplicationContext(), "下载失败", 0).show();
break;
case CHANGE_TEXTPROCESS:
tv_process.setText("下载进度:"+pb.getProgress()*100/pb.getMax()+"%");
break;
case SERVER_ERROR:
Toast.makeText(getApplicationContext(), "服务器错误", 0).show();
break;
case DOWNLOAD_SUCCESS:
Toast.makeText(getApplicationContext(), "下载完成", 0).show();
break;
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
et_path = (EditText) findViewById(R.id.et_path);
pb = (ProgressBar) findViewById(R.id.pb);
tv_process = (TextView) findViewById(R.id.tv_process);
}
/**
* 点击下载事件
* @param view
*/
public void downLoad(View view) {
final String path = et_path.getText().toString().trim();
if (path != null && !"".equals(path)) {
new Thread() {
public void run() {
// String path = "http://localhost:8080/qvod.exe";
// String path = "http://localhost:8080/demo.txt";
// String path =
// "http://www.cnblogs.com/Googler/archive/2010/08/19/1803700.html";
try {
URL url = new URL(path);
HttpURLConnection conn = (HttpURLConnection) url
.openConnection();
conn.setConnectTimeout(5000);
conn.setRequestMethod("GET");
int code = conn.getResponseCode();
System.out.println("请求码:" + code);
if (code == 200) {
// 获取资源长度
int length = conn.getContentLength();
pb.setMax(length); //设置进度条最大值
System.out.println("文件长度为:" + length);
// 定义一个随机访问文件
// RandomAccessFile randomFile = new
// RandomAccessFile("demo.txt",
// "rwd");
RandomAccessFile randomFile = new RandomAccessFile(
"/sdcard/qvod.exe", "rwd");
randomFile.setLength(length);// 设置文件长度
randomFile.close();
// 计算每个线程下载的数据
int blockSize = length / threadCount;
for (int threadId = 1; threadId <= threadCount; threadId++) {
int startIndex = (threadId - 1) * blockSize;
int endIndex = (threadId == threadCount) ? length - 1
: threadId * blockSize - 1;
System.out
.println("线程" + threadId + "[ "
+ startIndex + "--->"
+ endIndex + " ]");
TempDataOpenHeandler tempData = new TempDataOpenHeandler(
MainActivity.this);
new DownloadThread(path, startIndex, endIndex,
threadId,tempData).start();
}
}
else {
System.out.println("服务器出现错误、、、");
Message msg = new Message();
msg.what = SERVER_ERROR;
handler.sendMessage(msg);
}
}
catch (Exception e) {
e.printStackTrace();
Message msg = new Message();
msg.what = DOWNLOAD_ERROR;
handler.sendMessage(msg);
}
};
}.start();
}
else {
Toast.makeText(this, "路径错误", 0).show();
return;
}
}
/**
* 多线程下载
*
* @author Dream
*
*/
private class DownloadThread extends Thread {
private String path; // 资源路径
private int startIndex; // 开始位置
private int endIndex; // 结束位置
private int threadId; // 线程号
private TempDataOpenHeandler tempData = null;
public DownloadThread(String path, int startIndex, int endIndex,
int threadId,TempDataOpenHeandler tempData) {
this.path = path;
this.startIndex = startIndex;
this.endIndex = endIndex;
this.threadId = threadId;
this.tempData = tempData;
}
@Override
public void run() {
SQLiteDatabase db = tempData.getWritableDatabase();
try {
Cursor cursor = db.query("tempInfo",
new String[] { "startIndex" }, "id=?",
new String[] { threadId+"" }, null, null, null);
if (cursor.moveToNext()) {
int realStartIndex = cursor.getInt(0);
currentProcess += realStartIndex - startIndex;
startIndex = realStartIndex;
// System.out.println("线程"+threadId+"的每次开始位置为"+startIndex+"--------------------------------");
}else{
ContentValues values = new ContentValues();
values.put("id", threadId);
values.put("startIndex", 0);
db.insert("tempInfo", null, values);
}
cursor.close();
db.close();
// // 获取断点的开始位置
// File tempFile = new File("/sdcard/"+threadId + ".txt");
// if (tempFile.exists() && tempFile.length() > 0) {
//
// FileInputStream tempIn = new FileInputStream(tempFile);
// int leng = 0;
// byte[] tempBuff = new byte[1024];
//
// int len = tempIn.read(tempBuff);
// int downLoadStart = Integer.parseInt(new String(tempBuff,
// 0, len));
// startIndex = downLoadStart;
// }
System.out.println("线程" + threadId + "真实开始位置:[ " + startIndex
+ "--->" + endIndex + " ]");
URL url = new URL(path);
HttpURLConnection conn = (HttpURLConnection) url
.openConnection();
conn.setConnectTimeout(5000);
conn.setRequestMethod("GET");
conn.setRequestProperty("Range", "bytes=" + startIndex + "-"
+ endIndex);
int code = conn.getResponseCode();// 注意此处如果请求全部的资源的返回200,部分资源返回206
System.out.println("code:" + code);
InputStream in = conn.getInputStream();
RandomAccessFile randomFile = new RandomAccessFile(
"/sdcard/qvod.exe", "rwd");
// RandomAccessFile randomFile = new
// RandomAccessFile("demo.txt", "rwd");
randomFile.seek(startIndex);// 设置文件开始位置
int total = 0;
int len = 0;
byte[] buff = new byte[1024];
while ((len = in.read(buff)) != -1) {
// RandomAccessFile info = new
// RandomAccessFile("/sdcard/"+threadId
// + ".txt", "rwd");
randomFile.write(buff, 0, buff.length);
total += len;
System.out.println("线程" + threadId + ":total=" + total);
db = tempData.getWritableDatabase();
db.execSQL("UPDATE tempInfo set startIndex = ? WHERE id = ?", new Object[]{total+startIndex,threadId});
db.close();
synchronized (MainActivity.this) {
currentProcess += len; //累计下载量
pb.setProgress(currentProcess); //设置下载进度
Message msg = Message.obtain(); //从消息池中取消息
msg.what = CHANGE_TEXTPROCESS;
handler.sendMessage(msg);
}
// info.write((total + startIndex + "").getBytes());
// info.close();
}
in.close();
randomFile.close();
}
catch (Exception e) {
e.printStackTrace();
}
finally {
// new File(threadId + ".txt").delete();
synchronized (MainActivity.this) {
threadNum--;
System.out.println("线程"+threadId+"下载完成!!!");
if (threadNum == 0) {
db = tempData.getWritableDatabase();
db.execSQL("DELETE FROM tempInfo");
db.close();
// for (int i = 1; i <= threadCount; i++) {
// new File("/sdcard/" + i + ".txt").delete();
// }
System.out.println("文件下载完成,删除所有临时文件");
Message msg = new Message();
msg.what = DOWNLOAD_SUCCESS;
handler.sendMessage(msg);
}
}
}
}
}
}
相关文章推荐
- android多线程下载以及断点续传
- android 多线程下载
- Android中多线程下载
- Android开发_使用HttpURLConnection实现多线程下载
- android HTTP实现文件多线程下载
- android 多线程下载 支持断点续传的工具类
- Android中多线程下载
- Android http 多线程下载
- android HttpURLConnection实现多线程下载
- [转]Android:使用URL和URLConnection(多线程下载)
- android 客户端多线程下载
- Android通过HTTP协议实现多线程下载
- android实现多线程下载
- android 多线程下载 显示进度 速度
- Android中级篇之多线程下载
- Android 多线程下载
- Android中多线程下载方面的知识点
- Android开发(23)--java中的多线程下载
- Android之 多线程下载、断点续传 实现
- android实现多线程下载