一、断点下载原理:
使用多线程下载文件可以更快完成文件的下载,多线程下载文件之所以快,是因为其抢占的服务器资源多。如:假设服务器同时最多服务100个用户,在服务器中一条线程对应一个用户,100条线程在计算机中并非并发执行,而是由CPU划分时间片轮流执行,如果A应用使用了99条线程下载文件,那么相当于占用了99个用户的资源,假设一秒内CPU分配给每条线程的平均执行时间是10ms,A应用在服务器中一秒内就得到了990ms的执行时间,而其他应用在一秒内只有10ms的执行时间。就如同一个水龙头,每秒出水量相等的情况下,放990毫秒的水肯定比放10毫秒的水要多。
多线程下载的实现过程:
1>首先得到下载文件的长度,然后设置本地文件的长度。
HttpURLConnection.getContentLength(); RandomAccessFile file = new RandomAccessFile("QQWubiSetup.exe","rwd"); file.setLength(filesize);//设置本地文件的长度
2>根据文件长度和线程数计算每条线程下载的数据长度和下载位置。如:文件的长度为6M,线程数为3,那么,每条线程下载的数据长度为2M,每条线程开始下载的位置如上图所示。
3>使用Http的Range头字段指定每条线程从文件的什么位置开始下载,下载到什么位置为止,如:指定从文件的2M位置开始下载,下载到位置(4M-1byte)为止,代码如下:
HttpURLConnection.setRequestProperty("Range", "bytes=2097152-4194303");
4>保存文件,使用RandomAccessFile类指定每条线程从本地文件的什么位置开始写入数据。
RandomAccessFile threadfile = new RandomAccessFile("QQWubiSetup.exe ","rwd"); threadfile.seek(2097152);//从文件的什么位置开始写入数据
5、每条线程下载的长度分析:
二、代码实现:
1、界面布局
<RelativeLayout 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:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".MainActivity" > <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/path" /> <LinearLayout android:id="@+id/linearLayout1" android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="horizontal" > </LinearLayout> <!-- 下面是进度条,有两种一种是环形进度条,另一种是水平进度条, 环形进度条,是一种没有刻度的,也叫做不确定性进度条 --> <ProgressBar android:id="@+id/progressBar" style="?android:attr/progressBarStyleHorizontal" android:layout_width="fill_parent" android:layout_height="18dp" /> <!-- style="" 样式,水平进度条的样式,由android系统提供的 --> <!-- 用来显示进度条的百分比 --> <TextView android:id="@+id/resultView" android:layout_width="fill_parent" android:layout_height="wrap_content" android:gravity="center" android:textColor="#ffffff" /> <Button android:id="@+id/stopbutton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBaseline="@+id/button" android:layout_alignBottom="@+id/button" android:layout_marginLeft="22dp" android:layout_toRightOf="@+id/button" android:enabled="false" android:text="@string/stopbutton" /> <EditText android:id="@+id/path" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_below="@+id/linearLayout1" android:layout_marginTop="36dp" android:ems="10" android:text="http://192.168.8.101:8080/Simple/easyMule-Setup.exe" /> <Button android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignLeft="@+id/path" android:layout_below="@+id/path" android:layout_marginLeft="14dp" android:layout_marginTop="14dp" android:text="@string/button" /> </RelativeLayout>