欢迎访问悦橙教程(wld5.com),关注java教程。悦橙教程  java问答|  每日更新
页面导航 : > > 文章正文

Android多线程实现文件断点下载,android断点下载,download_mai

来源: javaer 分享于  点击 36845 次 点评:27

Android多线程实现文件断点下载,android断点下载,download_mai


download_main_layout.xml:

<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" > <EditText android:id="@+id/down_load_edt" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="20dp" android:hint="请输入下载文件的网址!" /> <Button android:layout_marginTop="20dp" android:id="@+id/down_load_btn" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="点击下载" /> <ProgressBar android:id="@+id/down_load_pbar" style="?android:attr/progressBarStyleHorizontal" android:layout_width="match_parent" android:layout_height="wrap_content" /></LinearLayout>

下载入口Activity:

public class MainActivity extends Activity implements OnClickListener {/下载文件按钮 */private Button downLoadBtn;/下载文件地址 /private EditText downLoadEdt;/下载进度 */private ProgressBar downLoadPbar;/定义发送消息的字段/private static final int MESSAGE_NUMBER = 1;/所要下载文件总大小 */private int fileSize;/已下载大小 /private int downLoadSize;/所下载文件的保存路径 */private String path;/更新进度条的值 /private Handler handler = new Handler() {@Overridepublic void handleMessage(Message msg) {super.handleMessage(msg);if (msg.what == MESSAGE_NUMBER) {/设置进度*/downLoadPbar.setProgress(Double.valueOf(downLoadSize * 1.0 / fileSize * 100).intValue());}}};@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.download_activity_main);findViews();setListeners();initdata();}private void findViews() {downLoadEdt=(EditText) findViewById(R.id.down_load_edt);downLoadBtn = (Button) findViewById(R.id.down_load_btn);downLoadPbar = (ProgressBar) findViewById(R.id.down_load_pbar);}private void setListeners() {downLoadBtn.setOnClickListener(this);}private void initdata() {downLoadPbar.setVisibility(View.GONE);downLoadPbar.setMax(100);downLoadPbar.setProgress(0);}@Overridepublic void onClick(View v) {/获取SDcard /path = Environment.getExternalStorageDirectory() + "/downloads/";File file = new File(path);if (!file.exists()) {file.mkdir();}/下载操作 */new Thread(new DownLoadTask()).start();/显示进度条 /downLoadPbar.setVisibility(View.VISIBLE);}/子线程,计算下载量,更新UI */class DownLoadTask implements Runnable {/线程块大小,每个线程的下载量 /private int blockSize;/ 默认为5个线程 */private int threadNum = 5;/ 下载后的文件名 /private String fileName = "myDownLoad.zip";@Overridepublic void run() {/数组保存线程对象,便于后面的每个线程下载量计算总和 */DownLoadThread[] fileDownLoads = new DownLoadThread[threadNum];/ 计算总大小 /URL url;try {url = new URL(downLoadEdt.getText().toString().trim());HttpURLConnection conn = (HttpURLConnection) url.openConnection();/计算下载量 */fileSize = conn.getContentLength();/ 计算每个线程的下载量 /blockSize = fileSize / threadNum;/ 执行下载操作 */for (int i = 0; i < threadNum; i++) {/ 每个线程的开始位置 /int begin = i * blockSize;/ 每个线程的结束位置 */int end = (i + 1) * blockSize - 1;DownLoadThread thread = new DownLoadThread(url, begin, end, path + fileName);thread.start();fileDownLoads[i] = thread;}/ 更新UI /boolean flag = false;while (!flag) {flag = true;for (int i = 0; i < threadNum; i++) {downLoadSize += fileDownLoads[i].getDownloadsize();if (!fileDownLoads[i].isFinish()) {flag = false;}}MainActivity.this.handler.sendEmptyMessage(MESSAGE_NUMBER);Thread.sleep(1000);}} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}}}}

下载线程工具类:

public class DownLoadThread extends Thread {/文件年在Url*/private URL url;/文件下载开始位置/private int startPostion;/文件下载结束位置*/private int endPostion;/文件下载当前位置/private int currentPostion;/文件名*/private String filename;/缓冲输入流/private BufferedInputStream buffin;/写入流,支持断点*/private RandomAccessFile raf;/缓冲大小/byte[] buffsize = new byte[1024];/已经下载大小*/private int downloadsize;/下载是否完成/private boolean isFinish;public int getDownloadsize() {return downloadsize;}public boolean isFinish() {return isFinish;}public DownLoadThread(URL url, int begin, int end, String filename) {super();this.url = url;this.startPostion = begin;this.endPostion = end;this.filename = filename;}@Overridepublic void run() {try {/ 抽象类 URLConnection 是所有类的超类,它代表应用程序和 URL 之间的通信链接。此类的实例可用于读取和写入此 URL 引用的资源。通常,创建一个到 URL 的连接需要几个步骤: * openConnection() connect()对影响到远程资源连接的参数进行操作。 与资源交互;查询头字段和内容。 * 通过在 URL 上调用 openConnection 方法创建连接对象。 处理设置参数和一般请求属性。 使用 connect 方法建立到远程对象的实际连接。 远程对象变为可用。远程对象的头字段和内容变为可访问。 /URLConnection conn = url.openConnection();/指定下载的范围/conn.setRequestProperty("Range", "bytes="+startPostion+"-"+endPostion);/此URL将在一定的上下文环境中被检验,是否允许用户交互,比如弹出一个认证对话框。如果为 false,那么不允许用户交互。*/conn.setAllowUserInteraction(true);/做缓冲优化处理/buffin = new BufferedInputStream(conn.getInputStream());/写入本地文件*/raf = new RandomAccessFile(new File(filename), "rw");/移动到新的位置/raf.seek(startPostion);while(currentPostion<endPostion){//如果当前下载没有结束int size = buffin.read(buffsize, 0, 1024);/已经读完*/if(size==-1){break;}raf.write(buffsize, 0, size);currentPostion+=size;/下载量/downloadsize+=size;}isFinish = true;/下载完成就要关闭输入流与写入流/buffin.close();raf.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}super.run();}}

不要忘记在清单文件AndroidManifest.xml中设置相应权限: <!--网络访问权限--> <uses-permissionandroid:name="android.permission.INTERNET"/> <!--sdcard权限--> <uses-permissionandroid:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/> <uses-permissionandroid:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

相关栏目:

用户点评