您的位置:首页 > 移动开发 > Android开发

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);

}

}

}

}

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: