zoukankan      html  css  js  c++  java
  • android中级篇之多线程下载

    要是先多线程下载,则必须对同一个文件可任意位置的写入 ,java中提供这样一个类可任意写入RandomAccessFile 。通过多线程,可将文件分割成多个子断,每一个线程只需下载一段文件即可。实现效果如图:


     

    下面看代码部分:

    1.布局文件 main.xml

     

    [xhtml] view plaincopy
    1. <?xml version="1.0" encoding="utf-8"?>  
    2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    3.     android:orientation="vertical"  
    4.     android:layout_width="fill_parent"  
    5.     android:layout_height="fill_parent"  
    6.     >  
    7. <TextView    
    8.     android:layout_width="fill_parent"   
    9.     android:layout_height="wrap_content"   
    10.     android:text="下载路径"  
    11.     />  
    12. <EditText  
    13.     android:id="@+id/mEditText"  
    14.     android:layout_width="fill_parent"  
    15.     android:layout_height="wrap_content"  
    16.     android:singleLine="true"  
    17.     android:text="http://android.yesky.com/uploads/attachments/2010-04/27/a5964152.jpg"/>     
    18. <ProgressBar  
    19.     android:id="@+id/mBar"  
    20.     android:layout_width="fill_parent"  
    21.     android:layout_height="wrap_content"  
    22.     android:visibility="invisible"  
    23.     style="?android:attr/progressBarStyleHorizontal"/>     
    24. <Button  
    25.     android:id="@+id/mButton"  
    26.     android:layout_width="fill_parent"    
    27.     android:layout_height="wrap_content"  
    28.     android:text="下载"/>  
    29. </LinearLayout>  

     

     

    2.下载工具类 Download.java

     

    1. package com.yin.downloader.utils;  
    2. import java.io.File;  
    3. import java.io.IOException;  
    4. import java.io.InputStream;  
    5. import java.io.RandomAccessFile;  
    6. import java.net.HttpURLConnection;  
    7. import java.net.MalformedURLException;  
    8. import java.net.URL;  
    9. import android.content.Context;  
    10. import android.util.Log;  
    11. public class Download {  
    12.     private String SDPath = null;  
    13.     private static final String TAG = "com.yin.download";  
    14.     private RandomAccessFile randomFile = null;  
    15.     private URL  url;  
    16.     private Context context;  
    17.     private String urlStr;  
    18.     private String fileName;  
    19.     private int fileSize;  
    20.     private int totalReadSize;  
    21.     public Download(String urlStr,String fileName,String SDPath,Context context){  
    22.         this.context = context;  
    23.         this.fileName = fileName;  
    24.         this.urlStr = urlStr;  
    25.         this.SDPath = SDPath;  
    26.     }  
    27.       
    28.     public void downloadFile(){  
    29.         try {  
    30.             File file = new File(SDPath+fileName);  
    31.             url = new URL(urlStr);  
    32.             HttpURLConnection conn = (HttpURLConnection) url.openConnection();  
    33.             conn.setRequestMethod("GET");  
    34.             //获得下载文件的大小  
    35.             fileSize = conn.getContentLength();  
    36.             //设置线程的大小,考虑手机的性能,并不是越大越好  
    37.             int threadSize = 3;  
    38.             //每个线程下载文件+的部分大小        +1 避免文件下载不完全  
    39.             int block = fileSize / threadSize +1;  
    40.             for(int i=0;i<3;i++){  
    41.                 int startPosition = i * block;  
    42.                 //创建可任意位置读取的文件  
    43.                 randomFile = new RandomAccessFile(file, "rw");  
    44.                 randomFile.seek(startPosition);  
    45.                 new DownloadThread(i+1, startPosition, block, randomFile).start();  
    46.             }  
    47.           
    48.         } catch (MalformedURLException e) {  
    49.             Log.e(TAG, "MalformedURLException");  
    50.             e.printStackTrace();  
    51.         } catch (IOException e) {  
    52.             Log.e(TAG, "IOException");  
    53.             e.printStackTrace();  
    54.         }  
    55.     }  
    56.       
    57.     //下载文件的线程  
    58.     private class DownloadThread extends Thread{  
    59.           
    60.         private int threadID;  
    61.         private int startPosition;  
    62.         private int block;  
    63.         private RandomAccessFile randomFile;  
    64.         public DownloadThread(int threadID, int startPosition, int block,  
    65.                 RandomAccessFile randomFile) {  
    66.             super();  
    67.             this.threadID = threadID;  
    68.             this.startPosition = startPosition;  
    69.             this.block = block;  
    70.             this.randomFile = randomFile;  
    71.         }  
    72.           
    73.         public void run() {  
    74.             try {  
    75.                 HttpURLConnection conn = (HttpURLConnection) url.openConnection();  
    76.                 conn.setRequestMethod("GET");  
    77.                 //文件下载位置   规定的格式 “byte=xxxx-”  
    78.                 String start = "bytes="+startPosition + "-";  
    79.                 //设置文件开始的下载位置  
    80.                 conn.setRequestProperty("Range", start);  
    81.                 InputStream is = conn.getInputStream();  
    82.                 byte[] buffer = new byte[4*1024];  
    83.                 int len = -1;  
    84.                 int readFileSize = 0;  
    85.                 while((readFileSize < block) && ((len = is.read(buffer)) != -1)){  
    86.                     randomFile.write(buffer,0,len);  
    87.                     readFileSize += len ;  
    88.                     totalReadSize += readFileSize;  
    89.                 }  
    90.                 System.out.println("线程 :"+threadID+" 下载完成");      
    91.                 is.close();  
    92.                 randomFile.close();  
    93.                 conn.disconnect();  
    94.                   
    95.             } catch (IOException e) {  
    96.                 Log.e(TAG+":child""IOException");  
    97.                 e.printStackTrace();  
    98.             }  
    99.         }  
    100.     }  
    101.     public int getFileSize() {  
    102.         return fileSize;  
    103.     }  
    104.     public void setFileSize(int fileSize) {  
    105.         this.fileSize = fileSize;  
    106.     }  
    107.     public int getTotalReadSize() {  
    108.         return totalReadSize;  
    109.     }  
    110.     public void setTotalReadSize(int totalReadSize) {  
    111.         this.totalReadSize = totalReadSize;  
    112.     }  
    113. }  

     

    3.DownloadActivity.java

     

    1. package com.yin.downloader;  
    2. import java.util.Timer;  
    3. import java.util.TimerTask;  
    4. import android.app.Activity;  
    5. import android.os.Bundle;  
    6. import android.os.Environment;  
    7. import android.os.Handler;  
    8. import android.os.Message;  
    9. import android.view.View;  
    10. import android.view.View.OnClickListener;  
    11. import android.widget.Button;  
    12. import android.widget.EditText;  
    13. import android.widget.ProgressBar;  
    14. import android.widget.Toast;  
    15. import com.yin.downloader.utils.Download;  
    16. public class DownloadActivity extends Activity {  
    17.     public EditText mEditText;  
    18.     public ProgressBar mBar;  
    19.     public Button mButton;  
    20.     public String urlStr;  
    21.     public String fileName;  
    22.     public String SDPath = "/sdcard/";  
    23.     public int fileSize;  
    24.     public int totalReadSize;  
    25.     Download download;  
    26.       
    27.     public Handler handler = new Handler(){  
    28.         @Override  
    29.         public void handleMessage(Message msg) {  
    30.               
    31.             mBar.setProgress(download.getTotalReadSize());  
    32.             mBar.invalidate();  
    33.         }  
    34.           
    35.     };  
    36.       
    37.     public Timer mTimer = new Timer();  
    38.     public TimerTask mTask = new TimerTask() {  
    39.           
    40.         @Override  
    41.         public void run() {  
    42.             Message msg = new Message();  
    43.             handler.sendMessage(msg);  
    44.         }  
    45.     };  
    46.       
    47.     public void onCreate(Bundle savedInstanceState) {  
    48.         super.onCreate(savedInstanceState);  
    49.         setContentView(R.layout.main);  
    50.         mEditText = (EditText) findViewById(R.id.mEditText);  
    51.         mBar = (ProgressBar) findViewById(R.id.mBar);  
    52.         mButton = (Button) findViewById(R.id.mButton);  
    53.         mButton.setOnClickListener(new ClickEven());  
    54.           
    55.         fileName = "my.jpg";  
    56.         //判断SDcard是否存在。  
    57.         if(Environment.getExternalStorageState() == Environment.MEDIA_MOUNTED){  
    58.             SDPath ="/sdcard/";  
    59.         }else{  
    60.             Toast.makeText(this"SDcard不存在", Toast.LENGTH_LONG).show();  
    61.         }  
    62.         
    63.     }  
    64.       
    65.     private class ClickEven implements OnClickListener{  
    66.           
    67.         public void onClick(View v) {  
    68.             urlStr = mEditText.getText().toString();  
    69.             mBar.setVisibility(View.VISIBLE);  
    70.             download = new Download(urlStr,fileName,SDPath,DownloadActivity.this);  
    71.             download.downloadFile();  
    72.             //将progressbar的大小设置为下载文件大小  
    73.             mBar.setMax(download.getFileSize());  
    74.             //定时刷新  
    75.             mTimer.schedule(mTask, 0200);  
    76.         }  
    77.           
    78.     }  
    79. }  

    此例实现比较简单,还可以加入断点续传的功能,把程序停止时当前线程现在的位置存入数据库中,再次下载时从数据库中取出即可;

  • 相关阅读:
    使用jQuery对象
    jQuery插件
    使用jQuery函数
    jQuery的两把利器
    初始jQuery
    BOM——特效
    BOM的介绍
    DOM——节点操作
    miaov- 自动生成正V反V大于号V小于号V楼梯等图案
    H5 -- 本地存储计数器的值 和前端校验用户
  • 原文地址:https://www.cnblogs.com/zhwl/p/2548004.html
Copyright © 2011-2022 走看看