<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
收藏助手
不良信息举报
0条评论