一个下载小demo
来源:互联网 发布:长春网络营销软件价格 编辑:程序博客网 时间:2024/04/30 23:47
一个基于HttpURLConnection的下载小demo,支持多线程下载,断点续传下载,重点学习HttpConnection应用,和断点续传,一个很基本,一个很实用
public class MainActivity extends AppCompatActivity{ String path = "http://192.168.51.121:8080/liangzhu.mp3"; int threadCount = 3; private ProgressBar pb; private TextView tv; private Button btn; int curentProgress = 0; String sdCardDir = Environment.getExternalStorageDirectory().getPath(); String sdRoot = sdCardDir+"/mrpeng/"; // String sdRoot = "sdcard/"; int finishedThread = 0; Handler handler = new Handler() { @Override public void handleMessage(Message msg) { tv.setText(pb.getProgress()*100/pb.getMax()+"%"); } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); pb = (ProgressBar)findViewById(R.id.pb); tv = (TextView)findViewById(R.id.tv); btn = (Button)findViewById(R.id.btn); btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Thread thread = new Thread() { @Override public void run() { try { URL url = new URL(path); HttpURLConnection conn = (HttpURLConnection)url.openConnection(); conn.setRequestMethod("GET"); conn.setConnectTimeout(8000); conn.setReadTimeout(8000); if(conn.getResponseCode() == 200) { //文件大小 int length = conn.getContentLength(); pb.setMax(length); //计算每条线程下载的字节数 int size = length/threadCount; for(int i = 0; i<threadCount; i++) { int startIndex = i*size; int endIndex = ( i+1 )*size-1; if(i == threadCount-1) { endIndex = length-1; } Log.e("hhaha", length+"线程"+i+"的下载区间是:"+startIndex+" ~ "+endIndex); new DownLoadThread(i, startIndex, endIndex).start(); } } }catch(Exception e) { e.printStackTrace(); } } }; thread.start(); } }); } private String getFileNameFromUrl(String path) { int index = path.lastIndexOf("/"); return path.substring(index+1); } private class DownLoadThread extends Thread { int threadId; int startIndex; int endIndex; public DownLoadThread(int threadId, int startIndex, int endIndex) { this.threadId = threadId; this.startIndex = startIndex; this.endIndex = endIndex; } /** * 下载逻辑 */ @Override public void run() { File parent = new File(sdRoot); if(!parent.exists()) { parent.mkdir(); } File fileProgress = new File(sdRoot+threadId+".txt"); int lastProgress = 0; if(fileProgress.exists()) { //读取上次下载记录 try { FileInputStream fis = new FileInputStream(fileProgress); BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(fis)); //上次的下载记录 lastProgress = Integer.parseInt(bufferedReader.readLine()); startIndex += lastProgress;//注意,此处为内部类变量,只累加当前线程的下载进度 curentProgress += lastProgress;//此为全局变量,累加全部的下载进度 pb.setProgress(curentProgress); handler.sendEmptyMessage(0); fis.close(); }catch(Exception e) { e.printStackTrace(); } } try { URL url = new URL(path); HttpURLConnection conn = (HttpURLConnection)url.openConnection(); conn.setRequestMethod("GET"); conn.setConnectTimeout(8000); conn.setReadTimeout(8000); //设置请求的数据区间 conn.setRequestProperty("Range", "bytes="+startIndex+"-"+endIndex); if(conn.getResponseCode() == 206) { InputStream is = conn.getInputStream(); byte[] bytes = new byte[1024]; int len = 0; //当前线程下载的总长,初始值是上一次下载的进度 int total = lastProgress; File file = new File(sdRoot+getFileNameFromUrl(path)); RandomAccessFile raf = new RandomAccessFile(file, "rwd"); raf.seek(startIndex); while(( len = is.read(bytes) ) != -1)//从此输入流中将最多 bytes.length 个字节的数据读入一个 byte 数组中。 { raf.write(bytes, 0, len);//将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此文件输出流。 total += len; //临时文件 RandomAccessFile rafProgress = new RandomAccessFile(fileProgress, "rwd"); rafProgress.write(( total+"" ).getBytes()); rafProgress.close(); curentProgress += len; pb.setProgress(curentProgress); handler.sendEmptyMessage(0); } raf.close(); finishedThread++; //所有线程下载完毕之后,一起删除记录现在进度的文件 synchronized(path) { if(finishedThread == 3) { for(int i = 0; i<threadCount; i++) { File f = new File(sdRoot+i+".txt"); f.delete(); } finishedThread = 0; } } } }catch(Exception e) { e.printStackTrace(); } } }}
权限
<uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
源码:源码地址
0 0
- 一个下载小demo
- 一个api小demo
- 一个小demo
- 一个小demo
- 一个小demo
- 小demo例子: 上传&&下载
- 离线下载的小demo
- 第一步:写一个带进度条的下载文件的小Demo
- WCF的一个小Demo
- xml的一个小Demo
- appium跑一个小demo
- DotNetMQ的一个小demo
- 【MyBatis-02】一个小Demo
- 简单的一个小Demo
- 一个工具类小demo
- 一个学习编程的demo下载网站
- javascript读写cookie的一个小demo
- 关于分页的一个小demo
- Java 关键字synchronized解析
- Ubuntu下通过ppa安装jdk
- 在使用android:theme时爆出了一个java.lang.IllegalStateException
- 使用hide来切换fragmnent时实现切换更新
- MFC中listctrl的使用
- 一个下载小demo
- Solr中的Document、Field、Schema
- 如何理解Spring的控制反转IOC和依赖注入DI思想
- C++写时拷贝,引用计数
- C++ 函数重载
- Swift 单例
- 0. 回掉函数
- Struts2零配置开发(注解Annotation的使用)一
- Java异常(输出[D@139a55问题)