Android的网络应用-使用HttpURLConnection
Android的网络应用-使用HttpURLConnection
实例:多线程下载
实现多线程的步骤:
1.创建URL对象。
2.获取指定URL对象所指向资源的大小。
3.在本地磁盘上创建一个与网络资源相同大小的空文件。
4.计算每条线程应该下载网络资源的哪个部分(从哪个字节开始,到哪个字节结束)
5.依次创建,启动多线程来下载网络资源的指定部分
创建项目:MultiThreadDown
程序清单
下载工具类:DownUtil.java
Activity:MultiThreadDown.java
项目运行效果:
package org.wwj.net;import java.io.InputStream;import java.io.RandomAccessFile;import java.net.HttpURLConnection;import java.net.URL;public class DownUtil{// 定义下载资源的路径private String path;// 指定所下载的文件的保存位置private String targetFile;// 定义需要使用多少线程下载资源private int threadNum;// 定义下载的线程对象private DownloadThread[] threads;// 定义下载的文件的总大小private int fileSize;public DownUtil(String path, String targetFile, int threadNum){this.path = path;this.threadNum = threadNum;// 初始化threads数组threads = new DownloadThread[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("User-Agent","Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.2; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)");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 DownloadThread(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 DownloadThread extends Thread{// 当前线程的下载位置private int startPos;// 定义当前线程负责下载的文件大小private int currentPartSize;// 当前线程需要下载的文件块private RandomAccessFile currentPart;// 定义已经该线程已下载的字节数public int length;public DownloadThread(int startPos, int currentPartSize,RandomAccessFile currentPart){this.startPos = startPos;this.currentPartSize = currentPartSize;this.currentPart = currentPart;}@Overridepublic 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)) != -1){currentPart.write(buffer, 0, hasRead);// 累计该线程下载的总大小length += hasRead;}currentPart.close();inStream.close();}catch (Exception e){e.printStackTrace();}}}}
package org.wwj.net;import java.util.Timer;import java.util.TimerTask;import android.app.Activity;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.EditText;import android.widget.ProgressBar;public class MultiThreadDown extends Activity{EditText url;EditText target;Button downBn;ProgressBar bar;DownUtil downUtil;private int mDownStatus;@Overridepublic void onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.main);// 获取程序界面中的三个界面控件url = (EditText) findViewById(R.id.url);target = (EditText) findViewById(R.id.target);downBn = (Button) findViewById(R.id.down);bar = (ProgressBar) findViewById(R.id.bar);// 创建一个Handler对象final Handler handler = new Handler(){@Overridepublic void handleMessage(Message msg){if (msg.what == 0x123){bar.setProgress(mDownStatus);}}};downBn.setOnClickListener(new OnClickListener(){@Overridepublic void onClick(View v){// 初始化DownUtil对象downUtil = new DownUtil(url.getText().toString(),target.getText().toString(), 4);try{// 开始下载downUtil.download();}catch (Exception e){e.printStackTrace();}// 定义每秒调度获取一次系统的完成进度final Timer timer = new Timer();timer.schedule(new TimerTask(){@Overridepublic void run(){// 获取下载任务的完成比率double completeRate = downUtil.getCompleteRate();mDownStatus = (int) (completeRate * 100);// 发送消息通知界面更新进度条handler.sendEmptyMessage(0x123);// 下载完全后取消任务调度if (mDownStatus >= 100){timer.cancel();}}}, 0, 100);}});}}
<!-- 在SD卡中创建与删除文件权限 --><uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/><!-- 向SD卡写入数据权限 --><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/><!-- 授权访问网络 --><uses-permission android:name="android.permission.INTERNET"/>
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:orientation="vertical"android:layout_width="fill_parent"android:layout_height="fill_parent"><TextViewandroid:layout_width="fill_parent" android:layout_height="wrap_content"android:text="要下载的资源的URL:"/><EditTextandroid:id="@+id/url" android:layout_width="fill_parent" android:layout_height="wrap_content"android:text="http://www.crazyit.org/attachment.php?aid=1093&k=4ec76aeaa41ee84acf667b420e926783&t=1297311085"/><TextViewandroid:layout_width="fill_parent" android:layout_height="wrap_content"android:text="目标文件:"/><EditTextandroid:id="@+id/target" android:layout_width="fill_parent" android:layout_height="wrap_content"android:text="/mnt/sdcard/a.rar"/><Buttonandroid:id="@+id/down" android:layout_width="fill_parent" android:layout_height="wrap_content"android:text="@string/down"/><!-- 定义一个水平进度条,用于显示下载进度 --><ProgressBarandroid:id="@+id/bar" android:layout_width="fill_parent" android:layout_height="wrap_content"android:max="100"style="@android:style/Widget.ProgressBar.Horizontal"/></LinearLayout>