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

android文件分段下载

2016-03-08 23:31 375 查看
以下代码非原创,其中我的分析作为注释添加在代码,特此声明!

public class MainApp extends Activity implements OnClickListener {

private static final String TAG = MainApp.class.getSimpleName();

private TextView mMessageView;
private ProgressBar mProgressbar;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.progress_activity);
findViewById(R.id.download_btn).setOnClickListener(this);
mMessageView = (TextView) findViewById(R.id.download_message);
mProgressbar = (ProgressBar) findViewById(R.id.download_progress);
}

@Override
public void onClick(View v) {
if (v.getId() == R.id.download_btn) {
doDownload();
}
}

/**
* ʹ使用Handler来处理UI
*/
@SuppressLint("HandlerLeak")
Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
//根据key值size获取数据
mProgressbar.setProgress(msg.getData().getInt("size"));
//获得已下载长度所占的比例
float temp = (float) mProgressbar.getProgress()
/ (float) mProgressbar.getMax();
//获得已下载长度所占的百分比
int progress = (int) (temp * 100);
if (progress == 100) {
Toast.makeText(MainApp.this, "下载成功", Toast.LENGTH_LONG).show();
}
mMessageView.setText("已下载:" + progress + " %");

}
};

/**
* 下载文件
*/
private void doDownload() {
// 获取手机里的存储介质路径
String path = Environment.getExternalStorageDirectory()
+ "/amosdownload/";
//创建文件
File file = new File(path);
// 如果文件不存在,则按path路径创建文件夹
if (!file.exists()) {
file.mkdir();
}
// 设置mProgressbar为0
mProgressbar.setProgress(0);

//所下载的文件所处的地址
String downloadUrl = "http://gdown.baidu.com/data/wisegame/91319a5a1dfae322/baidu_16785426.apk";
//String downloadUrl = "http://192.168.253.1/My_Learn/uploads/love.txt";
//下载后的文件名
String fileName = "baidu.apk";
//将文件分成5段下载
int threadNum = 5;
//下载后的文件所处的绝对文件路径
String filepath = path + fileName;
Log.d(TAG, "download file  path:" + filepath);
//启动下载任务线程
downloadTask task = new downloadTask(downloadUrl, threadNum, filepath);
task.start();
}

/**
* 文件下载线程
*
*/
class downloadTask extends Thread {
private String downloadUrl;//文件下载路径ַ
private int threadNum;// 分成段数
private String filePath;// 存储路径ַ
private int blockSize;// 每一文件块大小

public downloadTask(String downloadUrl, int threadNum, String fileptah) {
this.downloadUrl = downloadUrl;
this.threadNum = threadNum;
this.filePath = fileptah;
}

@Override
public void run() {

FileDownloadThread[] threads = new FileDownloadThread[threadNum];
try {
URL url = new URL(downloadUrl);
Log.d(TAG, "download file http path:" + downloadUrl);
//打开网络连接
URLConnection conn = url.openConnection();
// 获得文件的以byte计算的长度
int fileSize = conn.getContentLength();
if (fileSize <= 0) {
System.out.println("无法获得文件信息");
return;
}
// 设置进度条的最大值
mProgressbar.setMax(fileSize);

//每一个文件块的长度
blockSize = (fileSize % threadNum) == 0 ? fileSize / threadNum
: fileSize / threadNum + 1;

Log.d(TAG, "fileSize:" + fileSize + "  blockSize:"+blockSize);

File file = new File(filePath);
for (int i = 0; i < threads.length; i++) {
//让每一个FileDownloadThread线程分段下载
threads[i] = new FileDownloadThread(url, file, blockSize,
(i + 1));
//为线程设置一个名字
threads[i].setName("Thread:" + i);
threads[i].start();
}
//是否下载完成标志
boolean isfinished = false;
int downloadedAllSize = 0;
while (!isfinished) {
isfinished = true;
// downloadedAllSize为已下载总长度
downloadedAllSize = 0;
for (int i = 0; i < threads.length; i++) {
downloadedAllSize += threads[i].getDownloadLength();
if (!threads[i].isCompleted()) {
isfinished = false;
}
}
//
Message msg = new Message();
msg.getData().putInt("size", downloadedAllSize);
mHandler.sendMessage(msg);
// Log.d(TAG, "current downloadSize:" + downloadedAllSize);
Thread.sleep(1000);// 每个1秒刷新一次
}
Log.d(TAG, " all of downloadSize:" + downloadedAllSize);

} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}

}
}

}


FileDownloadThread的代码
public class FileDownloadThread extends Thread {

private static final String TAG = FileDownloadThread.class.getSimpleName();

/** 是否完成标志 */
private boolean isCompleted = false;
/** 已下载长度 */
private int downloadLength = 0;
/**生成文件路径 */
private File file;
/**文件地址*/
private URL downloadUrl;
/** 下载线程编号 */
private int threadId;
/** 文件块大小 */
private int blockSize;

public FileDownloadThread(URL downloadUrl, File file, int blocksize,
int threadId) {
this.downloadUrl = downloadUrl;
this.file = file;
this.threadId = threadId;
this.blockSize = blocksize;
}

@Override
public void run() {

//缓冲输入流
BufferedInputStream bis = null;
RandomAccessFile raf = null;

try {
URLConnection conn = downloadUrl.openConnection();
//如果为 true,则在允许用户交互
conn.setAllowUserInteraction(true);

int startPos = blockSize * (threadId - 1);//该线程开始下载位置
int endPos = blockSize * threadId - 1;//该线程结束下载位置

//用来设置请求头文报属性,这里设置range范围
conn.setRequestProperty("Range", "bytes=" + startPos + "-" + endPos);
System.out.println(Thread.currentThread().getName() + "  bytes="
+ startPos + "-" + endPos);

byte[] buffer = new byte[1024];
bis = new BufferedInputStream(conn.getInputStream());
//能对file进行随意读写
raf = new RandomAccessFile(file, "rwd");
//移到所处该线程所应使用的位置
raf.seek(startPos);
int len;
//每次最多读1024个byte
while ((len = bis.read(buffer, 0, 1024)) != -1) {
//在buffer中写len个字节到文件file中
raf.write(buffer, 0, len);
downloadLength += len;
}
isCompleted = true;
Log.d(TAG, "current thread task has finished,all size:"
+ downloadLength);

} catch (IOException e) {
e.printStackTrace();
} finally {
if (bis != null) {
try {
//关闭输入流
bis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (raf != null) {
try {
raf.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

/**
* 查询是否下载完成
*/
public boolean isCompleted() {
return isCompleted;
}

/**
* 返回已下载长度
*/
public int getDownloadLength() {
return downloadLength;
}

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