import java.io.File; import java.net.URL; import java.net.URLConnection; import android.app.Activity; import android.os.Bundle; import android.os.Environment; import android.os.Handler; import android.os.Message; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.EditText; import android.widget.ProgressBar; import android.widget.TextView; /** * Copyright (C) 2010 ideasandroid * 演示android多线程下载 * 欢迎访问http://www.ideasandroid.com * 让程序开发不再那么神秘 */ public class FileDownloadDemo extends Activity { private EditText downloadUrl; private EditText downloadFileName; private EditText downloadThreadNum; private Button downloadBt; private ProgressBar downloadProgressBar; private TextView progressMessage; private int downloadedSize = 0 ; private int fileSize = 0 ; @Override public void onCreate(Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.main); downloadUrl = (EditText) findViewById(R.id.downloadUrl); downloadFileName = (EditText) findViewById(R.id.downloadFileName); downloadThreadNum = (EditText) findViewById(R.id.downloadThreadNum); progressMessage = (TextView) findViewById(R.id.progressMessage); downloadBt = (Button) findViewById(R.id.downloadBt); downloadProgressBar = (ProgressBar) findViewById(R.id.downloadProgressBar); downloadProgressBar.setVisibility(View.VISIBLE); downloadProgressBar.setMax( 100 ); downloadProgressBar.setProgress( 0 ); downloadBt.setOnClickListener( new OnClickListener() { public void onClick(View v) { download(); } }); } private void download() { // 获取SD卡目录 String dowloadDir = Environment.getExternalStorageDirectory() + " /ideasdownload/ " ; File file = new File(dowloadDir); // 创建下载目录 if ( ! file.exists()) { file.mkdirs(); } // 读取下载线程数,如果为空,则单线程下载 int downloadTN = Integer.valueOf( "" .equals(downloadThreadNum.getText() .toString()) ? " 1 " : downloadThreadNum.getText().toString()); // 如果下载文件名为空则获取Url尾为文件名 int fileNameStart = downloadUrl.getText().toString().lastIndexOf( " / " ); String fileName = "" .equals(downloadFileName.getText().toString()) ? downloadUrl .getText().toString().substring(fileNameStart) : downloadFileName.getText().toString(); // 开始下载前把下载按钮设置为不可用 downloadBt.setClickable( false ); // 进度条设为0 downloadProgressBar.setProgress( 0 ); // 启动文件下载线程 new downloadTask(downloadUrl.getText().toString(), Integer .valueOf(downloadTN), dowloadDir + fileName).start(); } Handler handler = new Handler() { @Override public void handleMessage(Message msg) { // 当收到更新视图消息时,计算已完成下载百分比,同时更新进度条信息 int progress = (Double.valueOf((downloadedSize * 1.0 / fileSize * 100 ))).intValue(); if (progress == 100 ) { downloadBt.setClickable( true ); progressMessage.setText( " 下载完成! " ); } else { progressMessage.setText( " 当前进度: " + progress + " % " ); } downloadProgressBar.setProgress(progress); } }; /** * @author ideasandroid * 主下载线程 */ public class downloadTask extends Thread { private int blockSize, downloadSizeMore; private int threadNum = 5 ; String urlStr, threadNo, fileName; public downloadTask(String urlStr, int threadNum, String fileName) { this .urlStr = urlStr; this .threadNum = threadNum; this .fileName = fileName; } @Override public void run() { FileDownloadThread[] fds = new FileDownloadThread[threadNum]; try { URL url = new URL(urlStr); URLConnection conn = url.openConnection(); // 获取下载文件的总大小 fileSize = conn.getContentLength(); // 计算每个线程要下载的数据量 blockSize = fileSize / threadNum; // 解决整除后百分比计算误差 downloadSizeMore = (fileSize % threadNum); File file = new File(fileName); for ( int i = 0 ; i < threadNum; i ++ ) { // 启动线程,分别下载自己需要下载的部分 FileDownloadThread fdt = new FileDownloadThread(url, file, i * blockSize, (i + 1 ) * blockSize - 1 ); fdt.setName( " Thread " + i); fdt.start(); fds[i] = fdt; } boolean finished = false ; while ( ! finished) { // 先把整除的余数搞定 downloadedSize = downloadSizeMore; finished = true ; for ( int i = 0 ; i < fds.length; i ++ ) { downloadedSize += fds[i].getDownloadSize(); if ( ! fds[i].isFinished()) { finished = false ; } } // 通知handler去更新视图组件 handler.sendEmptyMessage( 0 ); // 休息1秒后再读取下载进度 sleep( 1000 ); } } catch (Exception e) { } } } }
import java.io.BufferedInputStream; import java.io.File; import java.io.IOException; import java.io.RandomAccessFile; import java.net.URL; import java.net.URLConnection; import android.util.Log; /** * Copyright (C) 2010 ideasandroid * 演示android多线程下载 * 欢迎访问http://www.ideasandroid.com * 让程序开发不再那么神秘 * * 单个下载线程 */ public class FileDownloadThread extends Thread{ private static final int BUFFER_SIZE = 1024 ; private URL url; private File file; private int startPosition; private int endPosition; private int curPosition; // 用于标识当前线程是否下载完成 private boolean finished = false ; private int downloadSize = 0 ; public FileDownloadThread(URL url,File file, int startPosition, int endPosition){ this .url = url; this .file = file; this .startPosition = startPosition; this .curPosition = startPosition; this .endPosition = endPosition; } @Override public void run() { BufferedInputStream bis = null ; RandomAccessFile fos = null ; byte [] buf = new byte [BUFFER_SIZE]; URLConnection con = null ; try { con = url.openConnection(); con.setAllowUserInteraction( true ); // 设置当前线程下载的起点,终点 con.setRequestProperty( " Range " , " bytes= " + startPosition + " - " + endPosition); // 使用java中的RandomAccessFile 对文件进行随机读写操作 fos = new RandomAccessFile(file, " rw " ); // 设置开始写文件的位置 fos.seek(startPosition); bis = new BufferedInputStream(con.getInputStream()); // 开始循环以流的形式读写文件 while (curPosition < endPosition) { int len = bis.read(buf, 0 , BUFFER_SIZE); if (len == - 1 ) { break ; } fos.write(buf, 0 , len); curPosition = curPosition + len; if (curPosition > endPosition) { downloadSize += len - (curPosition - endPosition) + 1 ; } else { downloadSize += len; } } // 下载完成设为true this .finished = true ; bis.close(); fos.close(); } catch (IOException e) { Log.d(getName() + " Error: " , e.getMessage()); } } public boolean isFinished(){ return finished; } public int getDownloadSize() { return downloadSize; } }
转自http://www.goprogram.org/blog/?p=66
断点继传
最新推荐文章于 2023-07-07 14:10:22 发布