package com.mutildownloader; import java.io.File; import java.io.FileInputStream; import java.io.InputStream; import java.io.RandomAccessFile; import java.net.HttpURLConnection; import java.net.URL; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.text.TextUtils; import android.view.View; import android.widget.EditText; import android.widget.ProgressBar; import android.widget.TextView; import android.widget.Toast; import com.tenone.androidtest.R; public class MainActivity extends Activity { protected static final int DOWN_LOAD_ERROR = 0; public static final int DOWN_LOAD_FINISH = 1; protected static final int SERVICE_ERROR = 2; public static final int UPDATE_TEXT = 3; public static int threadCount = 3; public static int runningThread = 3; private EditText et_path; private ProgressBar pb; private TextView tv_process; public int currentPross;//当前的进度 private Handler handler = new Handler(){ @Override public void handleMessage(Message msg){ switch (msg.what){ case DOWN_LOAD_ERROR: Toast.makeText(getApplicationContext(), "下载失败", 0).show(); break; case DOWN_LOAD_FINISH: Toast.makeText(getApplicationContext(), "下载完成", 0).show(); break; case SERVICE_ERROR: Toast.makeText(getApplicationContext(), "服务器出错", 0).show(); break; case UPDATE_TEXT: tv_process.setText("当前进度:"+pb.getProgress()*100/pb.getMax()); break; } } }; @Override public void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.loader_layout); et_path = (EditText) findViewById(R.id.loader_text); pb = (ProgressBar) findViewById(R.id.loader_pb); tv_process = (TextView) findViewById(R.id.tv_process); } public void downLoad(View v){ final String path = et_path.getText().toString().trim(); if (TextUtils.isEmpty(path)){ Toast.makeText(this, "下载路径错误", 0).show(); return ; } new Thread(){ public void run(){ //1.连接服务器,获取一个文件并获取该文件的大小 //在本地创建一个大小跟服务器文件一样大的临时文件 try { //String path = "http://w.x.baidu.com/alading/anquan_soft_down_normal/13478/npp.6.6.9.Installer.1410249599.exe"; URL url = new URL(path); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setConnectTimeout(5000); conn.setRequestMethod("GET"); int code = conn.getResponseCode(); System.out.println("codemain:"+code); if (code == 200){ //服务器返回的数据长度,实际上是文件的长度 int length = conn.getContentLength(); pb.setMax(length);//设置进度条的最大值 System.out.println("文件总长度:"+length); //在客户端本地创建出一个和服务器端大小一样的文件 RandomAccessFile raf = new RandomAccessFile("/sdcard/setup.exe", "rwd"); //指定创建的这个文件的长度 raf.setLength(length); raf.close(); //计算出每个线程下载的文件大小 int blockSize = length / threadCount; for (int threadId=1; threadId<=threadCount; threadId++){ //线程下载的开始位子 int startIndex = (threadId - 1) * blockSize; //线程下载的结束位子 int endIndex = threadId * blockSize - 1; if (threadId == threadCount){ endIndex = length; } System.out.println("线程"+threadId+"下载:"+startIndex+"--->"+endIndex); new DownloadThread(threadId, startIndex, endIndex, path).start(); } }else{ Message msg = new Message(); msg.what = SERVICE_ERROR; handler.sendMessage(msg); System.out.println("服务器错误"); } } catch (Exception e) { e.printStackTrace(); Message msg = new Message(); msg.what = DOWN_LOAD_ERROR; handler.sendMessage(msg); } } }.start(); } public class DownloadThread extends Thread{ private int threadId; private int startIndex; private int endIndex; private String path; public DownloadThread(int threadId, int startIndex, int endIndex, String path) { super(); this.threadId = threadId; this.startIndex = startIndex; this.endIndex = endIndex; this.path = path; } @Override public void run(){ try { //检查是否存在记录下载长度的文件,如果存在读取这个文件的数据 File tempFile = new File("/sdcard/"+threadId+".txt"); if (tempFile.exists() && tempFile.length()>0){ FileInputStream fis = new FileInputStream(tempFile); byte[] temp = new byte[1024]; //读取长度为temp长度的数据到temp中,返回的是读取数据的长度,读到文件末尾返回-1 int leng = fis.read(temp); String downloadLen = new String(temp, 0, leng); int downloadlenInt = Integer.parseInt(downloadLen); int alreadyDownloadint = downloadlenInt - startIndex; currentPross+=alreadyDownloadint;//获取已经下载的进度 startIndex = downloadlenInt;//修改下载的真实的开始位置 System.out.println("线程"+threadId+"真实下载位置:"+startIndex+"--->"+endIndex); fis.close(); } URL url = new URL(path); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("GET"); //请求服务器下载部分文件指定文件的位置 conn.setRequestProperty("Range","bytes="+startIndex+"-"+endIndex); conn.setReadTimeout(5000); /* * 从服务器请求全部资源200 ok * 如果从服务器请求部分资源206 ok * */ int code = conn.getResponseCode(); System.out.println("code:"+code); //已经设置了请求的位置,返回的是当前位置对应的文件输入流 InputStream is = conn.getInputStream(); RandomAccessFile raf = new RandomAccessFile("/sdcard/setup.exe", "rwd"); //随机写文件的时候从哪个位置开始写 raf.seek(startIndex); int len = 0; byte[] buffer = new byte[1024]; //已经下载的数据 int total = 0; //记录当前线程下载数据的长度(方法一) //File file = new File(threadId+".text"); while ((len = is.read(buffer)) != -1){ //FileOutputStream fos = new FileOutputStream(file); //方法二 RandomAccessFile info = new RandomAccessFile("/sdcard/"+threadId+".txt", "rwd"); raf.write(buffer, 0, len); total+=len; info.write(String.valueOf(total+startIndex).getBytes()); info.close(); synchronized (MainActivity.this){ currentPross+=len;//获取当前的总进度 pb.setProgress(currentPross);//更改界面上progressbar进度条的进度 //特殊情况progressbar progressdialog进度条对话框可以直接在子线程里 //更新ui 内部代码特殊处理 //复用旧的消息避免过多的创建消息 Message msg =Message.obtain(); msg.what = UPDATE_TEXT; handler.sendMessage(msg); } //fos.write(String.valueOf(total).getBytes()); //fos.close(); } is.close(); raf.close(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); }finally{ threadFinish(); } } private synchronized void threadFinish() { runningThread--; if (runningThread == 0){//所有线程下载完成 for (int i=1; i<=3; i++){ File file = new File("/sdcard/"+i+".txt"); file.delete(); } System.out.println("文件下载完毕,删除所有的下载记录"); Message msg = new Message(); msg.what = DOWN_LOAD_FINISH; handler.sendMessage(msg); } } } }
android多线程断点下载(代码出自张泽华视频)
精选 转载
提问和评论都可以,用心的回复会被更多人看到
评论
发布评论
相关文章
-
【JAVA应用】多线程断点下载
多线程下载比单线程下载快,主要的原因是采用多线程下载,可以抢占更多的服务器资源。抢占Cpu的处理空间,实现更快的下载速度
多线程断点下载 Android开发 安卓 JAVA 源码