布局文件

文件多线程下载实现
 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:orientation="vertical" 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"> 2 - <LinearLayout android:id="@+id/ll" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> 3 - <EditText android:id="@+id/pathET" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:inputType="textUri" android:text="http://192.168.1.251:8080/WebServer/FeiQ.exe"> 4   <requestFocus />  5   </EditText> 6   <ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="download" android:src="@android:drawable/ic_media_play" />  7   </LinearLayout> 8   <ProgressBar android:id="@+id/downloadPB" style="?android:attr/progressBarStyleHorizontal" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@id/ll" android:layout_marginTop="20dp" />  9   <TextView android:id="@+id/percentTV" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/downloadPB" android:text="0%" /> 10   <TextView android:id="@+id/progressTV" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_below="@id/downloadPB" android:text="0/0" /> 11   </RelativeLayout>
View Code

MyHandler.java

文件多线程下载实现
 1 package com.itheima.download; 2  3 import java.io.File; 4 import java.io.FileOutputStream; 5 import java.io.IOException; 6 import java.io.InputStream; 7  8 import org.apache.http.HttpEntity; 9 10 import android.content.Context;11 12 import com.loopj.android.http.FileAsyncHttpResponseHandler;13 14 public abstract class MyFileHandler extends FileAsyncHttpResponseHandler {15     private boolean isCancel;16 17     public MyFileHandler(Context context) {18         super(context);19     }20 21     public MyFileHandler(File file) {22         super(file);23     }24 25     @Override26     protected byte[] getResponseData(HttpEntity entity) throws IOException {27         if (entity != null) {28             InputStream instream = entity.getContent();29             long contentLength = entity.getContentLength();30             FileOutputStream buffer = new FileOutputStream(getTargetFile(), true);31             if (instream != null) {32                 try {33                     byte[] tmp = new byte[BUFFER_SIZE];34                     int l, count = 0;35                     // do not send messages if request has been cancelled36                     while ((l = instream.read(tmp)) != -1 && !Thread.currentThread().isInterrupted()) {37                         if (isCancel)38                             break;39                         count += l;40                         buffer.write(tmp, 0, l);41                         sendProgressMessage(count, (int) contentLength);42                     }43                 } finally {44                     instream.close();45                     buffer.flush();46                     buffer.close();47                 }48             }49         }50         return null;51     }52     53     public void cancel() {54         isCancel = true;55     }56 57 }
View Code

MainActivity.java

文件多线程下载实现
 1 package com.itheima.download; 2  3 import java.io.File; 4  5 import android.app.Activity; 6 import android.os.Bundle; 7 import android.os.Environment; 8 import android.view.View; 9 import android.widget.EditText;10 import android.widget.ImageButton;11 import android.widget.ProgressBar;12 import android.widget.TextView;13 14 public class MainActivity extends Activity {15 16 //    private AsyncHttpClient client;17     18     private EditText pathET;19     private ProgressBar downloadPB;20     private TextView percentTV;21     private TextView progressTV;22     private DownloadTask task;23 24     @Override25     protected void onCreate(Bundle savedInstanceState) {26         super.onCreate(savedInstanceState);27         setContentView(R.layout.activity_main);28         29         pathET = (EditText) findViewById(R.id.pathET);30         downloadPB = (ProgressBar) findViewById(R.id.downloadPB);31         percentTV = (TextView) findViewById(R.id.percentTV);32         progressTV = (TextView) findViewById(R.id.progressTV);33         34 //        client = new AsyncHttpClient();35     }36     37     public void download(View v) {38         ImageButton ib = (ImageButton) v;39         40         if (task == null) {41             String targetUrl = pathET.getText().toString().trim();42             File localFile = new File(Environment.getExternalStorageDirectory(), targetUrl.substring(targetUrl.lastIndexOf("/") + 1));43             task = new DownloadTask(targetUrl, localFile, 3, this, downloadPB, percentTV, progressTV);44             task.execute();45             ib.setImageResource(android.R.drawable.ic_media_pause);46         } else {47             task.stop();48             task = null;49             ib.setImageResource(android.R.drawable.ic_media_play);50         }51     }52 53     /*54     public void classicDownload(View v) {55         String path = pathET.getText().toString().trim();56         File file = new File("/mnt/sdcard/", path.substring(path.lastIndexOf("/") + 1));57         58         client.get(path, new FileAsyncHttpResponseHandler(file) {        // 处理文件传输的处理器59             public void onSuccess(int statusCode, Header[] headers, File file) {60                 Toast.makeText(getApplicationContext(), "下载成功", Toast.LENGTH_SHORT).show();61             }62             public void onFailure(int statusCode, Header[] headers, Throwable throwable, File file) {63                 Toast.makeText(getApplicationContext(), "下载失败 " + statusCode, Toast.LENGTH_SHORT).show();64                 throwable.printStackTrace();65             }66             public void onProgress(int bytesWritten, int totalSize) {    // 下载或上传的进度67                 System.out.println(bytesWritten + " / " + totalSize + " (" + bytesWritten * 100 / totalSize + "%)");68             }69         });70     }71     */72 73 }
View Code

DownloadTask.java

文件多线程下载实现
  1 package com.itheima.download;  2   3 import java.io.File;  4 import java.io.FileInputStream;  5 import java.io.FileOutputStream;  6 import java.io.IOException;  7 import java.util.ArrayList;  8   9 import org.apache.http.Header; 10  11 import android.content.Context; 12 import android.widget.ProgressBar; 13 import android.widget.TextView; 14  15 import com.loopj.android.http.AsyncHttpClient; 16 import com.loopj.android.http.AsyncHttpResponseHandler; 17  18 public class DownloadTask { 19     private String targetUrl; 20     private File localFile; 21     private int threadAmount; 22     private Context context; 23     private ProgressBar downloadPB; 24     private TextView percentTV; 25     private TextView progressTV; 26  27     private long contentLength; 28     private long threadLength; 29     private ArrayList<File> cacheList = new ArrayList<File>(); 30     private ArrayList<MyFileHandler> handlerList = new ArrayList<MyFileHandler>(); 31      32     /** 33      * 创建下载任务 34      * @param targetUrl        目标地址 35      * @param localFile        本地路径 36      * @param threadAmount    线程数量 37      * @param context        应用环境 38      * @param downloadPB  39      * @param progressTV  40      * @param percentTV  41      */ 42     public DownloadTask(String targetUrl, File localFile, int threadAmount, Context context, ProgressBar downloadPB, TextView percentTV, TextView progressTV) { 43         super(); 44         this.targetUrl = targetUrl; 45         this.localFile = localFile; 46         this.threadAmount = threadAmount; 47         this.context = context; 48         this.downloadPB = downloadPB; 49         this.percentTV = percentTV; 50         this.progressTV = progressTV; 51     } 52  53     public void execute() { 54         new AsyncHttpClient().head(targetUrl, new AsyncHttpResponseHandler() {        // 根据URL向服务器发起一个请求, 获取响应头 55             public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) { 56                 caculateLength(headers);    // 获取文件总长度, 计算每个线程负责的长度 57                 beginDownload();            // 开启多个线程下载 58             } 59             public void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable error) { 60             } 61         }); 62     } 63      64     private void caculateLength(Header[] headers) {         65         for (Header header : headers)  66             if ("Content-Length".equals(header.getName()))  67                 contentLength = Long.parseLong(header.getValue());            // 从相应头中获取文件总大小 68         threadLength = (contentLength + threadAmount - 1) / threadAmount;    // 计算每个线程负责多少 69         downloadPB.setMax((int) contentLength);        // 设置进度条的最大刻度为文件总大小 70     } 71      72     private void beginDownload() { 73         for (int i = 0; i < threadAmount; i++) {    // 定义循环, 每次循环启动1个线程下载 74             File cacheFile = new File(context.getCacheDir(), localFile.getName() + ".temp" + i);    // 定义临时文件的路径 75             cacheList.add(cacheFile);                // 把文件装入集合 76              77             long begin = i * threadLength + cacheFile.length();        // 计算开始位置 78             long end = i * threadLength + threadLength - 1;            // 计算结束位置 79             System.out.println(i + ": " + begin + " - " + end); 80             if (begin > end) 81                 continue; 82              83             MyFileHandler fileHandler = new MyFileHandler(cacheFile) {            // 发送请求, 下载数据, 存储到临时文件 84                 private long ms; 85                 public void onSuccess(int statusCode, Header[] headers, File file) { 86                     System.out.println(Thread.currentThread().getName() + ": " + file + " 下载完成"); 87                     checkOtherThread();                // 检查其他线程是否下载完毕, 如果都完了, 合并文件 88                 } 89                 public void onFailure(int statusCode, Header[] headers, Throwable throwable, File file) { 90                 } 91                 public void onProgress(int bytesWritten, int totalSize) {    // 运行频率非常高 92                     if (System.currentTimeMillis() - ms > 100) { 93                         ms = System.currentTimeMillis(); 94                         updateProgress(); 95                     } 96                 } 97             }; 98             handlerList.add(fileHandler); 99             100             AsyncHttpClient client = new AsyncHttpClient();101             client.addHeader("Range", "bytes=" + begin + "-" + end);        // 设置请求数据的范围102             client.get(targetUrl, fileHandler);103         }104     }105     106     private void updateProgress() {107         long finishLength = getFinishLength();108         if (finishLength == 0)109             return;110         downloadPB.setProgress((int) finishLength);111         percentTV.setText(finishLength * 1000 / contentLength / 10f + "%"); 112         progressTV.setText(finishLength + "/" + contentLength);113     }114     115     private long getFinishLength() {116         long finishLength = 0;117         for (File cacheFile : cacheList)             // 遍历所有临时文件118             finishLength += cacheFile.length();        // 统计总长度119         return finishLength;120     }121 122     private void checkOtherThread() {123         if (getFinishLength() == contentLength) {     // 如果文件长度和ContentLength相等, 代表下载完成124             updateProgress();125             merge();                                // 合并所有的临时文件126         }127     }128 129     private void merge() {130         try {131             FileOutputStream out = new FileOutputStream(localFile);        132             for (File cacheFile : cacheList) {                                // 遍历所有临时文件133                 FileInputStream in = new FileInputStream(cacheFile);        134                 byte[] buffer = new byte[8192];135                 int length;136                 while ((length = in.read(buffer)) != -1)    // 读取每个文件137                     out.write(buffer, 0, length);            // 把每个文件的数据都写出到localFile138                 in.close();139                 cacheFile.delete();140             }141             out.close();142         } catch (IOException e) {143             throw new RuntimeException(e);144         }145     }146     147     public void stop() {148         for (MyFileHandler fileHandler : handlerList) {149             fileHandler.cancel();150         }151     }152 }
View Code

更多相关文章

  1. 基于Android TV端的文件选择器(UI比较丑,主要看逻辑)
  2. Android学习笔记(八)之Android 读写xml文件
  3. android使用多线程处理
  4. Android札记:防反编译、混淆文件p…
  5. 总结android中的.gradle文件写法及含义
  6. [Android Studio] 使用本地 aar 文件
  7. Android Studio 实时显示布局文件Preview窗口
  8. Android 学习 之 资源文件 动态修改strings.xml中的字符资源
  9. Android中通过其他线程更新主线程UI

随机推荐

  1. mysql语句如何插入含单引号或反斜杠的值
  2. mysql压缩包版zip安装配置方法
  3. Windows下mysql 8.0.12 安装详细教程
  4. windows10下mysql 8.0 下载与安装配置图
  5. MySQL PHP语法浅析
  6. Win10下mysql 8.0.15 安装配置方法图文教
  7. window下mysql 8.0.15 安装配置方法图文
  8. mysql 8.0.15 winx64解压版安装配置方法
  9. mysql 8.0.14 安装配置方法图文教程
  10. windows下mysql 8.0.13 解压版安装图文教