<html>
在tomcat6.0的webapps\ROOT下放一个.exe的可运行文件(若放.mp3、.jpg等格式的文件可能下载过程出现损坏还是能够查看的,若是.exe可运行文件下载过程出现损坏就不可运行了)。然后启动tomcat,双击bin目录下的startup.bat,出现下面的界面
记得不要关闭这个窗口,若关闭了后面的文件下载会出错的。
Android的布局文件代码例如以下:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity" >
<EditText
android:id="@+id/et_path"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:singleLine="true"
android:text="http://172.29.168.1:8088/fengxing.exe" />
<ProgressBar
android:id="@+id/pb"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="28dp" />
<Button
android:id="@+id/bt"
android:onClick="download"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="下载" />
<TextView
android:id="@+id/tv_show"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="眼下下载的进度:" />
</LinearLayout>
效果例如以下图:
为了方便,在代码中写死了下载路径。
MainActivity中的代码例如以下:
package com.myself.download;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.URL;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.app.Activity;
import android.text.TextUtils;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity {
protected static final int DOWN_LOAD_ERROR = 1;
protected static final int SERVER_ERROR = 2;
protected static final int SD_UNABLE = 3;
public static final int DOWN_LOAD_FINISH = 4;
public static final int UPDATE_TEXT = 5;
public static int threadCount = 3;
public static int runingThread =3;
public int currentProcess=0;//当前的进度
private EditText et_path;
private ProgressBar pb;
private TextView tv_show;
private Handler handler=new Handler(){
public void handleMessage(android.os.Message msg) {
switch (msg.what) {
case DOWN_LOAD_ERROR:
Toast.makeText(MainActivity.this, "下载错误", 1).show();
break;
case SERVER_ERROR:
Toast.makeText(MainActivity.this, "server连接错误", 1).show();
break;
case SD_UNABLE:
Toast.makeText(MainActivity.this, "SD卡不可用", 1).show();
break;
case DOWN_LOAD_FINISH:
Toast.makeText(MainActivity.this, "资源完成下载", 1).show();
break;
case UPDATE_TEXT:
tv_show.setText("眼下下载的进度:"+pb.getProgress()*100/pb.getMax()+"%");
break;
default:
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_show=(TextView) findViewById(R.id.tv_show);
}
public void download(View v){
final String path=et_path.getText().toString().trim();
if(TextUtils.isEmpty(path)){
Toast.makeText(this, "下载路径不能为空", 1).show();
return ;
}
new Thread(){
public void run() {
// 1.连接server,获取要下载的文件长度。并创建一个跟要下载资源大小一样的暂时文件
try {
//String path = "http://172.29.168.1:8088/fengxing.exe";
URL url = new URL(path);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(5000);
conn.setRequestMethod("GET");
int code = conn.getResponseCode();
System.out.println("code: "+code);
if (code == 200) {
// server返回的数据的长度实际上就是文件的长度
int length = conn.getContentLength();
pb.setMax(length);
//System.out.println("文件总长度:" + length);
//推断sd卡是否可用
if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
//在client创建一个与要下载的资源相同大小的暂时文件
RandomAccessFile raf=new RandomAccessFile("/sdcard/fengxing.exe", "rwd");
//设置文件的大小
raf.setLength(length);
raf.close();
// 如果是3个线程去下载
// 平均每个线程下载的资源的大小
int blockSize = length / threadCount;
for (int threadId = 1; threadId <= threadCount; threadId++) {
// 第一个线程開始下载的位置
int startIndex = (threadId - 1) * blockSize;
int endIndex = (threadId * blockSize) - 1;
if (threadId == threadCount) {// 最后一个线程下载的资源就是剩下的资源
endIndex = length;
}
System.out.println("线程"+threadId+"线程下载的位置: "+startIndex+"------->"+endIndex);
new DownlLoad(threadId, startIndex, endIndex, path).start();
}
}else{
System.out.println("sd卡不可用...");
Message msg=new Message();
msg.what=SD_UNABLE;
handler.sendMessage(msg);
}
} else {
System.out.println("server连接错误...");
Message msg=new Message();
msg.what=SERVER_ERROR;
handler.sendMessage(msg);
}
} catch (Exception e) {
e.printStackTrace();
Message msg=new Message();
msg.what=DOWN_LOAD_ERROR;
handler.sendMessage(msg);
}
};
}.start();
}
/**
* 下载文件的子线程 每个线程下载相应位置的文件
* @author Administrator
*
*/
public class DownlLoad extends Thread{
private int threadId;
private int startIndex;
private int endIndex;
private String path;
/**
*
* @param threadId 线程Id
* @param startIndex 開始下载的位置
* @param endIndex 结束位置
* @param path 要下载的资源所在路径
*/
public DownlLoad(int threadId, int startIndex, int endIndex, String path) {
this.threadId = threadId;
this.startIndex = startIndex;
this.endIndex = endIndex;
this.path = path;
}
@Override
public void run() {
try {
//检查是否存在记录了已经下载长度的文件。若存在则读取文件的内容
File tempFile=new File("/sdcard/"+threadId+".txt");
if(tempFile.exists()&&tempFile.length()>0){
FileInputStream fis=new FileInputStream(tempFile);
byte[] temp=new byte[1024];
int leng=fis.read(temp);
String downloadLen=new String(temp,0,leng);
int downloadInt=Integer.parseInt(downloadLen);
int alreadyDownInt=downloadInt-startIndex;//已经下载的进度
currentProcess+=alreadyDownInt;//若已经有下载的,又一次设置进度
startIndex=downloadInt;//改动下载真实的開始位置
}
URL url = new URL(path);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(5000);
conn.setRequestMethod("GET");
//重要:请求server下载部分的文件 指定下载的资源范围
conn.setRequestProperty("Range", "bytes="+startIndex+"-"+endIndex);
System.out.println("线程"+threadId+"线程又一次開始下载的位置: "+startIndex+"------->"+endIndex);
int code = conn.getResponseCode();//200代表的是全部的资源 206代表的是部分资源
//System.out.println("code:"+code);
if(code==206){
InputStream is=conn.getInputStream();//已经设置了请求的位置 返回当前位置相应的文件的输入流
RandomAccessFile raf=new RandomAccessFile("/sdcard/fengxing.exe", "rwd");
raf.seek(startIndex);//定位開始位置
int len=0;
byte[] buff=new byte[1024];
int total=0;//记录已经下载的文件的长度
while((len=is.read(buff))!=-1){
//FileOutputStream fos=new FileOutputStream(file);
RandomAccessFile file=new RandomAccessFile("/sdcard/"+threadId+".txt","rwd");//记录当前线程下载的长度
raf.write(buff, 0, len);
total+=len;
//System.out.println("线程"+threadId+" 下载长度:"+total);
file.write((""+(total+startIndex)).getBytes());
file.close();
//更新进度条
synchronized (MainActivity.this) {
currentProcess+=len;//获取全部线程下载的总进度
pb.setProgress(currentProcess);//更改进度条的进度
Message msg=Message.obtain();//复用旧的消息
msg.what=UPDATE_TEXT;
handler.sendMessage(msg);
}
}
is.close();
raf.close();
System.out.println("线程"+threadId+"完成下载...");
}else{
System.out.println("线程"+threadId+"下载失败...");
}
/*File deleteFile=new File(threadId+".txt");
deleteFile.delete();*/
} catch (Exception e) {
e.printStackTrace();
} finally{
threadFinish();
}
}
private synchronized void threadFinish() {
//这部分的作用:防止某一个记录文件在资源下载完后没有被删除
runingThread--;
if(runingThread==0){
for(int i=1;i<=3;i++){
File file=new File("/sdcard/"+i+".txt");
file.delete();
}
System.out.println("资源已经完成下载。删除全部的下载记录...");
Message msg=new Message();
msg.what=DOWN_LOAD_FINISH;
handler.sendMessage(msg);
}
}
}
}
执行的效果图:
在下载的过程中,退出程序,然后在打开程序,程序会接着在原来的基础上继续下载。
最后打开File Explor中的sdcard,就会发现下载的文件:
源码的下载地址:http://download.csdn.net/detail/dangnianmingyue_gg/9026189
版权声明:本文为博主原创文章。未经博主同意不得转载。
举报
- 本文已收录于下面专栏:
相关文章推荐
-
android 多线程断点续传下载 三
今天跟大家一起分享下android开发中比較难的一个环节,可能非常多人看到这个标题就会感觉头非常大,的确假设没有良好的编码能力和逻辑思维,这块是非常难搞明确的,前面2次总结中已经为大家分享过有关技术的一些基...
- idaretobe
- 2015-03-19 17:21
- 312
-
Android实现网络多线程断点续传下载
本演示样例介绍在Android平台下通过HTTP协议实现断点续传下载。 我们编写的是Andorid的HTTP协议多线程断点下载应用程序。直接使用单线程下载HTTP文件对我们来说是一件很easy...
- beijingshi1
- 2013-11-21 14:23
- 814
-
Android(五)数据存储之五网络多线程断点下载
们编写的是Andorid的HTTP多线程断点下载应用程序。由于之间我们学习的学习积累,直接使用单线程下载HTTP文件对我们来说是一件很easy的事。那么,多线程断点下载的难点在哪里?1.多线程下载。2.支持断点。 多线程下载: <img title="2010-03-03 传智播客—Android(五)数据存储之五网络多线程断点下载 - 长城 - 长城" src="http://lh4.ggpht.com/_FMPy3IVGHrs/S49SK45xqaI/AAAAAAAABms/B6bk9kJo_vU/632BF46FE91E93
- simgsg
- 2010-04-16 13:58
- 580
-
Android之多线程下载及断点续传
今天我们来接触一下多线程下载。当然也包含断点续传,我们能够看到 非常多下载器,当开通会员的时候下载东西的速度就变得快了很多,这是为什么呢?这就是跟今天讲的多线程有关系了,事实上就是多开了几个线程一起下...
- qq_33642117
- 2016-07-24 13:54
- 655
-
Android实现网络多线程断点续传下载
本演示样例介绍在Android平台下通过HTTP协议实现断点续传下载。 我们编写的是Andorid的HTTP协议多线程断点下载应用程序。直接使用单线程下载HTTP文件对我们来说是一件很easy...

- wszxl492719760
- 2012-12-29 21:14
- 401
-
android 多线程断点续传下载器
多线程断点下载流程图: 多线程断点续传下载原理介绍:
- mmdev
- 2012-06-23 19:24
- 963
-
android 实现多线程下载和断点续传
原文链接为 http://www.cnblogs.com/hanyonglu/archive/2012/02/20/2358801.html 如有侵权 请联系删除 本演示样例介绍在Android...
- lk_0x00
- 2017-06-07 10:36
- 193
-
android 多线程断点续传下载器
多线程断点下载流程图: 多线程断点续传下载原理介绍:
- java-mans
- 2012-06-23 19:24
- 345
收藏助手
不良信息举报
浙公网安备 33010602011771号
0条评论