• Android---53---多线程下载


    采用HttpURLConnection
    HttpURLConnection从继承URLConnection,它也可以被用来发送到指定的网站GET求
    POST求。

    办法:

    int getResponseCode ():
    获取server的响应代码

    String getResponseMessage ():
    获取server的响应消息

    String getResponseMethod ():
    获取发送请求的方法

    void setRequestMethod ():
    设置发送请求的方法


    多线程下载
    步骤:

    1.创建URL对象
    2.获取指定URL对象所指向资源的大小 由getContentLength()实现
    3.在本地磁盘上创建一个与网络资源同样大小的空文件
    4.计算每条线程应该下载网络资源的那个部分(从哪个字节開始,到哪个字节结束)
    5.依次创建、启动多条线程来下载网络资源的指定部分。

    下载工具类:

    public class DownUtil
    {
    	// 定义下载资源的路径
    	private String path;
    	// 指定所下载的文件的保存位置
    	private String targetFile;
    	// 定义须要使用多少线程下载资源
    	private int threadNum;
    	// 定义下载的线程对象
    	private DownThread[] threads;
    	// 定义下载的文件的总大小
    	private int fileSize;
    
    	public DownUtil(String path, String targetFile, int threadNum)
    	{
    		this.path = path;
    		this.threadNum = threadNum;
    		// 初始化threads数组
    		threads = new DownThread[threadNum];
    		this.targetFile = targetFile;
    	}
    
    	public void download() throws Exception
    	{
    		URL url = new URL(path);
    		HttpURLConnection conn = (HttpURLConnection) url.openConnection();
    		conn.setConnectTimeout(5 * 1000);
    		conn.setRequestMethod("GET");
    		conn.setRequestProperty(
    			"Accept",
    			"image/gif, image/jpeg, image/pjpeg, image/pjpeg, "
    			+ "application/x-shockwave-flash, application/xaml+xml, "
    			+ "application/vnd.ms-xpsdocument, application/x-ms-xbap, "
    			+ "application/x-ms-application, application/vnd.ms-excel, "
    			+ "application/vnd.ms-powerpoint, application/msword, */*");
    		conn.setRequestProperty("Accept-Language", "zh-CN");
    		conn.setRequestProperty("Charset", "UTF-8");
    		conn.setRequestProperty("Connection", "Keep-Alive");
    		// 得到文件大小
    		fileSize = conn.getContentLength();
    		conn.disconnect();
    		int currentPartSize = fileSize / threadNum + 1;
    		RandomAccessFile file = new RandomAccessFile(targetFile, "rw");
    		// 设置本地文件的大小
    		file.setLength(fileSize);
    		file.close();
    		for (int i = 0; i < threadNum; i++)
    		{
    			// 计算每条线程的下载的開始位置
    			int startPos = i * currentPartSize;
    			// 每一个线程使用一个RandomAccessFile进行下载
    			RandomAccessFile currentPart = new RandomAccessFile(targetFile,
    				"rw");
    			// 定位该线程的下载位置
    			currentPart.seek(startPos);
    			// 创建下载线程
    			threads[i] = new DownThread(startPos, currentPartSize,
    				currentPart);
    			// 启动下载线程
    			threads[i].start();
    		}
    	}
    
    	// 获取下载的完毕百分比
    	public double getCompleteRate()
    	{
    		// 统计多条线程已经下载的总大小
    		int sumSize = 0;
    		for (int i = 0; i < threadNum; i++)
    		{
    			sumSize += threads[i].length;
    		}
    		// 返回已经完毕的百分比
    		return sumSize * 1.0 / fileSize;
    	}
    
    	private class DownThread extends Thread
    	{
    		// 当前线程的下载位置
    		private int startPos;
    		// 定义当前线程负责下载的文件大小
    		private int currentPartSize;
    		// 当前线程须要下载的文件块
    		private RandomAccessFile currentPart;
    		// 定义已经该线程已下载的字节数
    		public int length;
    
    		public DownThread(int startPos, int currentPartSize,
    			RandomAccessFile currentPart)
    		{
    			this.startPos = startPos;
    			this.currentPartSize = currentPartSize;
    			this.currentPart = currentPart;
    		}
    
    		@Override
    		public void run()
    		{
    			try
    			{
    				URL url = new URL(path);
    				HttpURLConnection conn = (HttpURLConnection)url
    					.openConnection();
    				conn.setConnectTimeout(5 * 1000);
    				conn.setRequestMethod("GET");
    				conn.setRequestProperty(
    					"Accept",
    					"image/gif, image/jpeg, image/pjpeg, image/pjpeg, "
    					+ "application/x-shockwave-flash, application/xaml+xml, "
    					+ "application/vnd.ms-xpsdocument, application/x-ms-xbap, "
    					+ "application/x-ms-application, application/vnd.ms-excel, "
    					+ "application/vnd.ms-powerpoint, application/msword, */*");
    				conn.setRequestProperty("Accept-Language", "zh-CN");
    				conn.setRequestProperty("Charset", "UTF-8");
    				InputStream inStream = conn.getInputStream();
    				// 跳过startPos个字节,表明该线程仅仅下载自己负责哪部分文件。
    				inStream.skip(this.startPos);
    				byte[] buffer = new byte[1024];
    				int hasRead = 0;
    				// 读取网络数据,并写入本地文件
    				while (length < currentPartSize
    					&& (hasRead = inStream.read(buffer)) > 0)
    				{
    					currentPart.write(buffer, 0, hasRead);
    					// 累计该线程下载的总大小
    					length += hasRead;
    				}
    				currentPart.close();
    				inStream.close();
    			}
    			catch (Exception e)
    			{
    				e.printStackTrace();
    			}
    		}
    	}
    }
    


     

    Activity:

    public class MainActivity extends Activity {
    
    	EditText url;
    	EditText target;
    	Button downButton;
    	ProgressBar bar;
    	DownUtil downUtil;
    
    	private int mDownStatus;
    
    	@Override
    	protected void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    		setContentView(R.layout.activity_main);
    
    		url = (EditText) findViewById(R.id.url);
    		target = (EditText) findViewById(R.id.target);
    		downButton = (Button) findViewById(R.id.down);
    		bar = (ProgressBar) findViewById(R.id.bar);
    
    		final Handler handler = new Handler() {
    			@Override
    			public void handleMessage(Message msg) {
    				if (msg.what == 0x123) {
    					bar.setProgress(mDownStatus);
    				}
    			}
    		};
    		downButton.setOnClickListener(new OnClickListener() {
    
    			@Override
    			public void onClick(View v) {
    				downUtil = new DownUtil(url.getText().toString(), target
    						.getText().toString(), 6);
    				new Thread() {
    					public void run() {
    						try {
    							downUtil.download();
    						} catch (Exception e) {
    							// TODO Auto-generated catch block
    							e.printStackTrace();
    						}
    
    						final Timer timer = new Timer();
    						timer.schedule(new TimerTask() {
    
    							@Override
    							public void run() {
    								// 获取下载任务的完毕比率
    								double completeRate = downUtil
    										.getCompleteRate();
    								mDownStatus = (int) (completeRate * 100);
    								// 发送消息通知界面更新进度条
    								handler.sendEmptyMessage(0x123);
    								// 下载全然后取消任务调度
    								if (mDownStatus >= 100) {
    									timer.cancel();
    								}
    
    							}
    						}, 0, 100);
    
    					};
    
    				}.start();
    			}
    		});
    	}
    }
    


     

    版权声明:本文博主原创文章,博客,未经同意不得转载。

  • 相关阅读:
    I Show
    Centos上安装Google Authenticator
    linux 上mailx通过465端口发送邮件
    Win10 RDP CredSSP报错处理
    linux 双网卡代理上网
    English trip EM3-LP2B Teacher:Taylor
    【BZOJ1984】月下“毛景树”-树链剖分
    c++ 数据对拍器
    【BZOJ2157】旅游-树链剖分
    游戏-博弈论-树形DP
  • 原文地址:https://www.cnblogs.com/blfshiye/p/4884355.html
Copyright © 2020-2023  润新知