安卓开发:多线程断点续传下载文件
程序员文章站
2022-07-06 08:46:48
一个简单的界面: item.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" tools:context=".MainActivity" > <EditText android:id="@+id/et_path" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="请输入下载路径(网址):" /> <EditText android:id="@+id/et_threadCount" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="请输入开启线程数量(建议不超过5):" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="click" android:text="开始下载" /> <LinearLayout android:id="@+id/ll_pb" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" ></LinearLayout> </LinearLayout>
item.xml:
<?xml version="1.0" encoding="utf-8"?> <ProgressBar xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/progressBar1" style="?android:attr/progressBarStyleHorizontal" android:layout_width="match_parent" android:layout_height="wrap_content" />
代码:
package org.dreamtech.download; 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 java.util.ArrayList; import java.util.List; import android.os.Bundle; import android.os.Environment; import android.app.Activity; import android.view.View; import android.widget.EditText; import android.widget.LinearLayout; import android.widget.ProgressBar; public class MainActivity extends Activity { private EditText et_path; private EditText et_threadCount; private LinearLayout ll_pb_layout; private static int runningThread; private String path; private int threadCount; private List<ProgressBar> pbLists; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); et_path = (EditText) findViewById(R.id.et_path); et_threadCount = (EditText) findViewById(R.id.et_threadCount); ll_pb_layout = (LinearLayout) findViewById(R.id.ll_pb); pbLists = new ArrayList<ProgressBar>(); } public void click(View v) { path = et_path.getText().toString().trim(); threadCount = Integer.parseInt(et_threadCount.getText().toString() .trim()); ll_pb_layout.removeAllViews(); pbLists.clear(); for (int i = 0; i < threadCount; i++) { ProgressBar pbView = (ProgressBar) View.inflate( getApplicationContext(), R.layout.item, null); pbLists.add(pbView); ll_pb_layout.addView(pbView); } new Thread() { public void run() { try { URL url = new URL(path); HttpURLConnection conn = (HttpURLConnection) url .openConnection(); conn.setRequestMethod("GET"); conn.setConnectTimeout(5000); int code = conn.getResponseCode(); if (code == 200) { int length = conn.getContentLength(); runningThread = threadCount; System.out.println("length:" + length); RandomAccessFile rafAccessFile = new RandomAccessFile( getFilename(path), "rw"); rafAccessFile.setLength(length); int blockSize = length / threadCount; for (int i = 0; i < threadCount; i++) { int startIndex = i * blockSize; int endIndex = (i + 1) * blockSize - 1; if (i == threadCount - 1) { endIndex = length - 1; } DownLoadThread downLoadThread = new DownLoadThread( startIndex, endIndex, i); downLoadThread.start(); } } } catch (Exception e) { e.printStackTrace(); } } }.start(); } private class DownLoadThread extends Thread { private int startIndex; private int endIndex; private int threadId; private int PbMaxSize; private int pblastPosition; public DownLoadThread(int startIndex, int endIndex, int threadId) { this.startIndex = startIndex; this.endIndex = endIndex; this.threadId = threadId; } @Override public void run() { try { PbMaxSize = endIndex - startIndex; URL url = new URL(path); HttpURLConnection conn = (HttpURLConnection) url .openConnection(); conn.setRequestMethod("GET"); conn.setConnectTimeout(5000); File file = new File(Environment.getExternalStorageDirectory() .getPath() + "/" + getFilename(path) + threadId + ".txt"); if (file.exists() && file.length() > 0) { FileInputStream fis = new FileInputStream(file); BufferedReader bufr = new BufferedReader( new InputStreamReader(fis)); String lastPositionn = bufr.readLine(); int lastPosition = Integer.parseInt(lastPositionn); pblastPosition = lastPosition - startIndex; startIndex = lastPosition + 1; fis.close(); } conn.setRequestProperty("Range", "bytes=" + startIndex + "-" + endIndex); int code = conn.getResponseCode(); if (code == 206) { RandomAccessFile raf = new RandomAccessFile( getFilename(path), "rw"); raf.seek(startIndex); InputStream in = conn.getInputStream(); int len = -1; byte[] buffer = new byte[1024 * 1024]; int total = 0; while ((len = in.read(buffer)) != -1) { raf.write(buffer, 0, len); total += len; int currentThreadPosition = startIndex + total; RandomAccessFile raff = new RandomAccessFile( getFilename(path) + threadId + ".txt", "rwd"); raff.write(String.valueOf(currentThreadPosition) .getBytes()); raff.close(); pbLists.get(threadId).setMax(PbMaxSize); pbLists.get(threadId).setProgress( pblastPosition + total); } raf.close(); synchronized (DownLoadThread.class) { runningThread--; if (runningThread == 0) { for (int i = 0; i < threadCount; i++) { File delteFile = new File(getFilename(path) + i + ".txt"); delteFile.delete(); } } } } } catch (Exception e) { } } } public String getFilename(String path) { int start = path.lastIndexOf("/") + 1; String subString = path.substring(start); String filename = Environment.getExternalStorageDirectory().getPath()+"/"+subString; return filename; } }
开权限:
<uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>