android加了进度条和进度文本多线程断点续传下载
我们要用进度条首先要改变它的样式,变成水平的
<ProgressBar
android:id="@+id/pro"
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="@android:style/Widget.ProgressBar.Horizontal"
/>
更新进度条不需要handle
然后我们要在三个地方设置进度条,首先要在第一次请求长度的时候设置进度条的最大值pro.setMax(length);
然后在下载的时候把每次的进度加起来,然后设置当前进度pro.setProgress(progress);
最后要实现断点续传读取进度文件里的时候设置进度,为了就是断了之后进度条能够更新;
文本进度条要用textview来实现,更新它就需要用handle来更新了
package com.example.threaddownload; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.InputStream; import java.io.InputStreamReader; import java.io.RandomAccessFile; import java.net.HttpURLConnection; import java.net.URL; import android.os.Bundle; import android.os.Environment; import android.os.Handler; import android.app.Activity; import android.view.View; import android.view.View.OnClickListener; import android.widget.ProgressBar; import android.widget.TextView; public class MainActivity extends Activity { private static String path = "http://192.168.21.1:8080/ok/TGPSetup.exe"; private static int threadCount = 3; private static int finishThread = 0; //添加进度条 private ProgressBar pro; //进度数 private int progress; //添加文本进度 private TextView tv; private Handler handler = new Handler(){ public void handleMessage(android.os.Message msg) { //如果有的时候下载的文件过大会出现负数改成long表示就可以了 tv.setText((long)pro.getProgress()*100/pro.getMax()+"%"); }; }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); pro = (ProgressBar) findViewById(R.id.pro); tv = (TextView) findViewById(R.id.tv); findViewById(R.id.start).setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { new Thread() { @Override public void run() { try { URL url = new URL(path); HttpURLConnection conn = (HttpURLConnection) url .openConnection(); conn.setRequestMethod("GET"); conn.setReadTimeout(5000); conn.setConnectTimeout(5000); if (conn.getResponseCode() == 200) { // 第一次请求要下载的长度 int length = conn.getContentLength(); pro.setMax(length); //给主线程发送消息 handler.sendEmptyMessage(1); // 应该从字符串中截取文件名称 File file = new File(Environment.getExternalStorageDirectory(),"TGPSetup.exe"); // 在下载之前生成临时文件,占位置 RandomAccessFile rdm = new RandomAccessFile( file, "rwd"); // 给临时文件大小 rdm.setLength(length); // 关闭 rdm.close(); // 计算每个线程应该下载的长度 int size = length / threadCount; // 为每个线程分配开始位置和结束位置 for (int i = 0; i < threadCount; i++) { int start = i * size; int end = (i + 1) * size - 1; // 最后一个线程的结束位置为总长度 if (i == threadCount - 1) { end = length; } // 每次都调用新的线程 new DownThread(start, end, i).start(); } } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } }.start(); } }); } // 线程 class DownThread extends Thread { private int start; private int end; private int threadId; public DownThread(int start, int end, int threadId) { this.start = start; this.end = end; this.threadId = threadId; } @Override public void run() { try { // 创建进度文件 File progressFile = new File(Environment.getExternalStorageDirectory(),threadId + ".txt"); // 判断是否有记录进度的文件,如果有的话把开始位置重新赋值 if (progressFile.exists()) { FileInputStream fis = new FileInputStream(progressFile); BufferedReader br = new BufferedReader( new InputStreamReader(fis)); int lastProgress =Integer.parseInt(br.readLine()); start += lastProgress; //上次下载的显示到进度条 progress+=lastProgress; pro.setProgress(progress); fis.close(); } System.out.println(threadId + "线程下载区间" + start + "---" + end); // 再次请求网络 URL url = new URL(path); HttpURLConnection conn = (HttpURLConnection) url .openConnection(); conn.setRequestMethod("GET"); conn.setReadTimeout(5000); conn.setConnectTimeout(5000); // 设置本次请求的文件的长度 conn.setRequestProperty("Range", "bytes=" + start + "-" + end); // 请求部分数据是206 if (conn.getResponseCode() == 206) { // 得到请求长度的文件输入流 InputStream is = conn.getInputStream(); byte[] b = new byte[1024]; int len = 0; // 记录每一次下载字节数 int totle = 0; // 应该从字符串中截取文件名称 File file = new File(Environment.getExternalStorageDirectory(),"TGPSetup.exe"); // 拿到之前占位置那个文件,相当于输出流 RandomAccessFile rdm = new RandomAccessFile(file, "rwd"); // 改变写入文件的开始位置 rdm.seek(start); while ((len = is.read(b)) != -1) { // 每次读取流里的数据写到临时文件里 rdm.write(b, 0, len); totle += len; progress+=len; handler.sendEmptyMessage(1); pro.setProgress(progress); System.out.println(threadId + "线程" + "下载了" + totle); // 把下载的总数存到进度文件里 RandomAccessFile rdm1 = new RandomAccessFile( progressFile, "rwd"); rdm1.write((totle + "").getBytes()); rdm1.close(); } rdm.close(); finishThread++; // 下载结束删除进度文件 if (finishThread == threadCount) { // 加同步锁 synchronized (path) { for (int i = 0; i < threadCount; i++) { File f = new File(Environment.getExternalStorageDirectory(),i + ".txt"); f.delete(); } finishThread = 0; } } } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }