<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次总结中已经为大家分享过有关技术的一些基...

Android实现网络多线程断点续传下载

本演示样例介绍在Android平台下通过HTTP协议实现断点续传下载。 我们编写的是Andorid的HTTP协议多线程断点下载应用程序。直接使用单线程下载HTTP文件对我们来说是一件很easy...

Android(五)数据存储之五网络多线程断点下载

们编写的是Andorid的HTTP多线程断点下载应用程序。由于之间我们学习的学习积累,直接使用单线程下载HTTP文件对我们来说是一件很easy的事。那么,多线程断点下载的难点在哪里?1.多线程下载。2.支持断点。 多线程下载: <img title="2010-03-03 传智播客—Android(五)数据存储之五网络多线程断点下载 - 长城 - 长城" src="http://lh4.ggpht.com/_FMPy3IVGHrs/S49SK45xqaI/AAAAAAAABms/B6bk9kJo_vU/632BF46FE91E93

Android之多线程下载及断点续传

今天我们来接触一下多线程下载。当然也包含断点续传,我们能够看到 非常多下载器,当开通会员的时候下载东西的速度就变得快了很多,这是为什么呢?这就是跟今天讲的多线程有关系了,事实上就是多开了几个线程一起下...

Android实现网络多线程断点续传下载

本演示样例介绍在Android平台下通过HTTP协议实现断点续传下载。 我们编写的是Andorid的HTTP协议多线程断点下载应用程序。

直接使用单线程下载HTTP文件对我们来说是一件很easy...

android 多线程断点续传下载器

多线程断点下载流程图: 多线程断点续传下载原理介绍:
  • mmdev
  • mmdev
  • 2012-06-23 19:24
  • 963

android 实现多线程下载和断点续传

原文链接为 http://www.cnblogs.com/hanyonglu/archive/2012/02/20/2358801.html 如有侵权 请联系删除 本演示样例介绍在Android...

android 多线程断点续传下载器

多线程断点下载流程图: 多线程断点续传下载原理介绍:
  • 微博
    微信
    QQ
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多仅仅同意输入30个字)

posted @ 2017-08-17 16:43  clnchanpin  阅读(169)  评论(0编辑  收藏  举报