Andriod 实现多线程断点下载demo
2014-05-02 17:25
453 查看
源码下载↓↓↓
实现功能大体思路:
1.首先根据线程数量,来划分每个线程下载文件的位置;
公式:开始位置=(线程序号-1)*(文件大小/线程数量)
结束位置= 线程序号*(文件大小/线程数量)-1
比如:文件大小是1000字节,用2个线程来下载,那么第一个线程下载的位置就是0-499,第二个就是500-1000
0 = (1-1)*(1000/2);
499 = 1*(1000/2)-1;
2.在发出http请求的时候设置请求参数,告诉服务器返回部分资源;con.setRequestProperty("Range","bytes=" + startIndex + "-"+endIndex);
3.下载文件的时候每个线程生成一个相应的下载记录,记录下载量,从而实现断点下载的功能;
先来个效果图:
![](http://img.blog.csdn.net/20140502172258703?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXEyNDczMDA5NDg=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
好了,其他就不说了,上代码;
点击下载源码
实现功能大体思路:
1.首先根据线程数量,来划分每个线程下载文件的位置;
公式:开始位置=(线程序号-1)*(文件大小/线程数量)
结束位置= 线程序号*(文件大小/线程数量)-1
比如:文件大小是1000字节,用2个线程来下载,那么第一个线程下载的位置就是0-499,第二个就是500-1000
0 = (1-1)*(1000/2);
499 = 1*(1000/2)-1;
2.在发出http请求的时候设置请求参数,告诉服务器返回部分资源;con.setRequestProperty("Range","bytes=" + startIndex + "-"+endIndex);
3.下载文件的时候每个线程生成一个相应的下载记录,记录下载量,从而实现断点下载的功能;
先来个效果图:
好了,其他就不说了,上代码;
package com.example.down; import android.support.v7.app.ActionBarActivity; import android.support.v7.app.ActionBar; import android.support.v4.app.Fragment; import android.text.TextUtils; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.EditText; import android.widget.ProgressBar; import android.widget.TextView; import android.widget.Toast; import android.os.Build; public class MainActivity extends Activity { public static final int SUCCESS = 0; public static final int JD = 1; EditText editText; TextView textView; ProgressBar bar; Handler handler = new Handler(){ @Override public void handleMessage(Message msg) { // TODO Auto-generated method stub super.handleMessage(msg); switch (msg.what) { case SUCCESS: Toast.makeText(getApplicationContext(), "下载成功", 0).show(); break; case JD: Bundle b = msg.getData(); textView.setText("下载进度:"+b.getString("jd")); break; default: break; } } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); editText = (EditText)findViewById(R.id.et); bar = (ProgressBar)findViewById(R.id.pb); textView = (TextView)findViewById(R.id.tv); } public void click(View view){ final String url = editText.getText().toString().trim(); if(TextUtils.isEmpty(url)){ Toast.makeText(this, "请输入下载地址", 0).show(); }else{ bar.setProgress(0); bar.setMax(0); new Thread(new Runnable() { @Override public void run() { // TODO Auto-generated method stub DownLoad downLoad = new DownLoad(url, MainActivity.this, bar); try { downLoad.start(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); Toast.makeText(MainActivity.this, "下载异常", 0).show(); } } }).start(); } } }
package com.example.down; 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.Message; import android.widget.ProgressBar; import android.widget.Toast; public class DownLoad { Integer downTotal = 0; int totals = 0; int threadTotal = 3; String urlStr = "http://192.168.2.101:8080/QQ.exe"; String savePath = "/sdcard/QQ.exe"; Object obj; ProgressBar bar; public DownLoad(String url,Object o,ProgressBar bar){ urlStr = url; this.obj = o; this.bar = bar; } public void start() throws Exception { URL url = new URL(urlStr); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("GET"); connection.setConnectTimeout(5000); int code = connection.getResponseCode(); if(code == 200){ //获取下载文件大小 int dataLength = connection.getContentLength(); totals = dataLength; bar.setMax(totals); //创建下载到本地的文件大小,RandomAccessFile类支持文件随机写入"rwd"模式表示直接写入磁盘,不缓存到内存中 RandomAccessFile raf = new RandomAccessFile(savePath,"rwd"); raf.setLength(dataLength); raf.close(); //计算每个线程下载文件的起始位置 int bolckSize = dataLength / threadTotal; for(int threadId = 1;threadId <= threadTotal;threadId++){ int startIndex = (threadId-1) * bolckSize;//线程下载的起点位置 int endIndex = threadId * bolckSize-1;//线程下载的结束位置 if(threadId == threadTotal){//如果是最后一个线程,就直接下载到文件尾部 endIndex = dataLength; } //调用线程执行下载 new DownloadThread(urlStr,threadId, startIndex, endIndex,obj).start(); } }else{ System.out.println("链接失败"); } } public class DownloadThread extends Thread{ /**线程ID*/ private int threadId; /**线程开始下载位置*/ private int startIndex; /**线程结束下载位置*/ private int endIndex; /**线程下载文件路径*/ private String path; /**线程ID*/ private Object o; public DownloadThread(String path,int threadId, int startIndex, int endIndex,Object o) { this.path = path; this.threadId = threadId; this.startIndex = startIndex; this.endIndex = endIndex; this.o = o; } @Override public void run() { try { // TODO Auto-generated method stub File file = new File("/sdcard/"+threadId+".txt"); int downloadTotal = 0; //检查是否有下载记录,如果有记录,这初始化线程的下载位置 if(file.exists() && file.length() > 0){ FileInputStream fis = new FileInputStream(file); byte[] bt = new byte[1024]; int length = fis.read(bt); String downloadStr = new String(bt,0,length); downloadTotal = Integer.parseInt(downloadStr); startIndex += downloadTotal; synchronized (o) { downTotal += downloadTotal; } System.out.println("线程:"+threadId+" 继续开始下载:"+startIndex); } URL url = new URL(urlStr); HttpURLConnection con = (HttpURLConnection) url.openConnection(); con.setRequestMethod("GET"); //请求服务器下载部分资源,指定文件位置 con.setRequestProperty("Range","bytes=" + startIndex + "-"+endIndex); con.setConnectTimeout(5000); //得到服务器返回码,200是全部资料请求成功,206是部分资源请求成功 int code = con.getResponseCode(); if(code == 206){ InputStream is = con.getInputStream(); RandomAccessFile raf = new RandomAccessFile(savePath,"rwd"); raf.seek(startIndex); if(is != null){ byte [] data = new byte[1024]; int len = 0; while((len = is.read(data)) != -1){ //生成下载进度文件,保存下载进度,实现断点下载 RandomAccessFile info = new RandomAccessFile("/sdcard/"+threadId+".txt","rwd"); raf.write(data, 0, len); downloadTotal += len; info.write((""+downloadTotal).getBytes()); info.close(); //同步块为了防止线程修改下载总量的安全问题 synchronized (o) { downTotal += len; bar.setProgress(downTotal); System.out.println("下载进度:"+(downTotal*100/totals)); Message message = new Message(); message.what = MainActivity.JD; Bundle b = new Bundle(); b.putString("jd", (downTotal*100/totals)+""); message.setData(b); ((MainActivity)o).handler.sendMessage(message); } } raf.close(); is.close(); } } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); }finally{ System.out.println("线程:"+threadId+" 下载结束"); //判断是否下载完毕,如果下载完毕,则删除下载记录文件 if(downTotal == totals){ for(int i = 1; i <= threadTotal;i++){ File file = new File("/sdcard/"+i+".txt"); file.delete(); } Message message = new Message(); message.what = MainActivity.SUCCESS; ((MainActivity)o).handler.sendMessage(message); System.out.println("线程:"+threadId+" 下载结束,清除文件成功!"); } } } } }
<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" > <EditText android:id="@+id/et" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="http://192.168.2.101:8080/QQ.exe" android:ems="10" /> <ProgressBar android:id="@+id/pb" style="?android:attr/progressBarStyleHorizontal" android:layout_width="match_parent" android:layout_height="wrap_content" /> <TextView android:id="@+id/tv" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="下载进度:" /> <Button android:id="@+id/button1" android:onClick="click" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Button" /> </LinearLayout>
点击下载源码
相关文章推荐
- 多线程断点下载的代码实现
- 实现多线程断点下载可以运行
- 再次奉献源码,webservice实现的多线程断点文件上传下载
- Java实现多线程断点下载(下载过程中可以暂停)
- Android多线程实现文件断点下载
- 使用开源项目xutils实现多线程断点下载
- Android原生实现多线程断点下载
- android 多线程断点下载实现
- Android实现多线程断点下载
- 多线程断点文件下载实现
- 安卓开发-多线程常规实现+xUtils-master开源框架实现 断点下载
- android(26)(使用开源框架xutils实现多线程断点下载)
- Android实现网络多线程断点下载介绍
- (Android小应用)在Android中实现多线程断点下载(连载一)
- android多线程下载——--显示进度条,断点下载—--—(Demo)
- Java实现多线程断点下载
- 一个根据断点续传原理而实现的多线程下载的程序
- android简单实现多线程,断点下载和状态栏下载进度
- Android多线程断点下载简单实现
- Java实现断点下载Demo