时间:2021-05-20
本文实例讲述了Android实现多线程下载文件的方法。分享给大家供大家参考。具体如下:
多线程下载大概思路就是通过Range 属性实现文件分段,然后用RandomAccessFile 来读写文件,最终合并为一个文件
首先看下效果图:
创建工程 ThreadDemo
首先布局文件 threaddemo.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="下载地址" /> <TextView android:id="@+id/downloadurl" android:layout_width="fill_parent" android:layout_height="wrap_content" android:lines="5" /> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="线程数" /> <EditText android:id="@+id/downloadnum" android:layout_width="fill_parent" android:layout_height="wrap_content" /> <ProgressBar android:id="@+id/downloadProgressBar" android:layout_width="fill_parent" style="?android:attr/progressBarStyleHorizontal" android:layout_height="wrap_content" /> <TextView android:id="@+id/downloadinfo" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="下载进度 0" /> <Button android:id="@+id/downloadbutton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="开始下载" /> </LinearLayout><?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" ><TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="下载地址" /><TextViewandroid:id="@+id/downloadurl"android:layout_width="fill_parent" android:layout_height="wrap_content" android:lines="5"/><TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="线程数" /><EditTextandroid:id="@+id/downloadnum"android:layout_width="fill_parent" android:layout_height="wrap_content" /><ProgressBarandroid:id="@+id/downloadProgressBar"android:layout_width="fill_parent" style="?android:attr/progressBarStyleHorizontal" android:layout_height="wrap_content" /><TextViewandroid:id="@+id/downloadinfo"android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="下载进度 0"/><Buttonandroid:id="@+id/downloadbutton"android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="开始下载"/></LinearLayout>主界面 Acitivity
public class ThreadDownloadDemo extends Activity { private TextView downloadurl; private EditText downloadnum; private Button downloadbutton; private ProgressBar downloadProgressBar; private TextView downloadinfo; private int downloadedSize = 0; private int fileSize = 0; private long downloadtime; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.threaddemo); downloadurl = (TextView) findViewById(R.id.downloadurl); downloadurl.setText("http://file16.top100.cn/201105110911/AA5CC27CBE34DEB50A194581D1300881/Special_323149/%E8%8D%B7%E5%A1%98%E6%9C%88%E8%89%B2.mp3"); downloadnum = (EditText) findViewById(R.id.downloadnum); downloadinfo = (TextView) findViewById(R.id.downloadinfo); downloadbutton = (Button) findViewById(R.id.downloadbutton); downloadProgressBar = (ProgressBar) findViewById(R.id.downloadProgressBar); downloadProgressBar.setVisibility(View.VISIBLE); downloadProgressBar.setMax(100); downloadProgressBar.setProgress(0); downloadbutton.setOnClickListener(new OnClickListener() { public void onClick(View v) { download(); downloadtime = SystemClock.currentThreadTimeMillis(); } }); } private void download() { // 获取SD卡目录 String dowloadDir = Environment.getExternalStorageDirectory() + "/threaddemodownload/"; File file = new File(dowloadDir); //创建下载目录 if (!file.exists()) { file.mkdirs(); } //读取下载线程数,如果为空,则单线程下载 int downloadTN = Integer.valueOf("".equals(downloadnum.getText() .toString()) ? "1" : downloadnum.getText().toString()); String fileName = "hetang.mp3"; //开始下载前把下载按钮设置为不可用 downloadbutton.setClickable(false); //进度条设为0 downloadProgressBar.setProgress(0); //启动文件下载线程 new downloadTask("http://file16.top100.cn/201105110911/AA5CC27CBE34DEB50A194581D1300881/Special_323149/%E8%8D%B7%E5%A1%98%E6%9C%88%E8%89%B2.mp3", 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) { downloadbutton.setClickable(true); downloadinfo.setText("下载完成!"); Dialog mdialog = new AlertDialog.Builder(ThreadDownloadDemo.this) .setTitle("提示信息") .setMessage("下载完成,总用时为:"+(SystemClock.currentThreadTimeMillis()-downloadtime)+"毫秒") .setNegativeButton("确定", new DialogInterface.OnClickListener(){ @Override public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); } }) .create(); mdialog.show(); } else { downloadinfo.setText("当前进度:" + progress + "%"); } downloadProgressBar.setProgress(progress); } }; 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(); //防止返回-1 InputStream in = conn.getInputStream(); //获取下载文件的总大小 fileSize = conn.getContentLength(); Log.i("bb", "======================fileSize:"+fileSize); //计算每个线程要下载的数据量 blockSize = fileSize / threadNum; // 解决整除后百分比计算误差 downloadSizeMore = (fileSize % threadNum); File file = new File(fileName); for (int i = 0; i < threadNum; i++) { Log.i("bb", "======================i:"+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.sendEmptyMessage(0); //线程暂停一秒 sleep(1000); } } catch (Exception e) { e.printStackTrace(); } } } } public class ThreadDownloadDemo extends Activity {private TextView downloadurl;private EditText downloadnum;private Button downloadbutton;private ProgressBar downloadProgressBar;private TextView downloadinfo;private int downloadedSize = 0;private int fileSize = 0;private long downloadtime;@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.threaddemo);downloadurl = (TextView) findViewById(R.id.downloadurl);downloadurl.setText("http://file16.top100.cn/201105110911/AA5CC27CBE34DEB50A194581D1300881/Special_323149/%E8%8D%B7%E5%A1%98%E6%9C%88%E8%89%B2.mp3");downloadnum = (EditText) findViewById(R.id.downloadnum);downloadinfo = (TextView) findViewById(R.id.downloadinfo);downloadbutton = (Button) findViewById(R.id.downloadbutton);downloadProgressBar = (ProgressBar) findViewById(R.id.downloadProgressBar);downloadProgressBar.setVisibility(View.VISIBLE);downloadProgressBar.setMax(100);downloadProgressBar.setProgress(0);downloadbutton.setOnClickListener(new OnClickListener() {public void onClick(View v) {download();downloadtime = SystemClock.currentThreadTimeMillis();}});}private void download() {// 获取SD卡目录String dowloadDir = Environment.getExternalStorageDirectory()+ "/threaddemodownload/";File file = new File(dowloadDir);//创建下载目录if (!file.exists()) {file.mkdirs();}//读取下载线程数,如果为空,则单线程下载int downloadTN = Integer.valueOf("".equals(downloadnum.getText().toString()) ? "1" : downloadnum.getText().toString());String fileName = "hetang.mp3";//开始下载前把下载按钮设置为不可用downloadbutton.setClickable(false);//进度条设为0downloadProgressBar.setProgress(0);//启动文件下载线程new downloadTask("http://file16.top100.cn/201105110911/AA5CC27CBE34DEB50A194581D1300881/Special_323149/%E8%8D%B7%E5%A1%98%E6%9C%88%E8%89%B2.mp3", Integer.valueOf(downloadTN), dowloadDir + fileName).start();}Handler handler = new Handler() {@Overridepublic void handleMessage(Message msg) {//当收到更新视图消息时,计算已完成下载百分比,同时更新进度条信息int progress = (Double.valueOf((downloadedSize * 1.0 / fileSize * 100))).intValue();if (progress == 100) {downloadbutton.setClickable(true);downloadinfo.setText("下载完成!");Dialog mdialog = new AlertDialog.Builder(ThreadDownloadDemo.this).setTitle("提示信息").setMessage("下载完成,总用时为:"+(SystemClock.currentThreadTimeMillis()-downloadtime)+"毫秒").setNegativeButton("确定", new DialogInterface.OnClickListener(){@Overridepublic void onClick(DialogInterface dialog, int which) {dialog.dismiss();}}).create();mdialog.show();} else {downloadinfo.setText("当前进度:" + progress + "%");}downloadProgressBar.setProgress(progress);}}; 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;}@Overridepublic void run() {FileDownloadThread[] fds = new FileDownloadThread[threadNum];try {URL url = new URL(urlStr);URLConnection conn = url.openConnection();//防止返回-1InputStream in = conn.getInputStream();//获取下载文件的总大小fileSize = conn.getContentLength();Log.i("bb", "======================fileSize:"+fileSize);//计算每个线程要下载的数据量blockSize = fileSize / threadNum;// 解决整除后百分比计算误差downloadSizeMore = (fileSize % threadNum);File file = new File(fileName);for (int i = 0; i < threadNum; i++) {Log.i("bb", "======================i:"+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.sendEmptyMessage(0);//线程暂停一秒sleep(1000);}}catch (Exception e) {e.printStackTrace();}}}}这里启动线程将文件分割为几个部分,每一个部分再启动一个线程去下载数据
下载文件的线程
这里通过RandomAccessFile 的seek方法定位到相应的位置 并实时记录下载量
当然这里需要联网和访问SD卡 所以要加上相应的权限
这样就OK了 下面可以看看断点续传的问题了。有待测试~~
希望本文所述对大家的Android程序设计有所帮助。
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
本文实例讲述了java多线程下载。分享给大家供大家参考,具体如下:使用多线程下载文件可以更快完成文件的下载,多线程下载文件之所以快,是因为其抢占的服务器资源多。
本文实例讲述了C#实现多线程下载文件的方法。分享给大家供大家参考。具体实现方法如下:usingSystem;usingSystem.Collections.Ge
多线程下载文件(支持暂停、取消、断点续传)多线程同时下载文件即:在同一时间内通过多个线程对同一个请求地址发起多个请求,将需要下载的数据分割成多个部分,同时下载,
本文实例讲述了Android实现多线程断点下载的方法。分享给大家供大家参考。具体实现方法如下:?12345678910111213141516171819202
多线程下载文件的思路:1.首先获取到文件的总大小获取文件大小的方式是通过网络读取,getContentLength()即可获取到文件的大小,使用RandomAc