iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >android怎么实现多线程断点续传功能
  • 426
分享到

android怎么实现多线程断点续传功能

android多线程 2023-05-30 17:05:26 426人浏览 安东尼
摘要

这篇文章主要介绍了Android怎么实现多线程断点续传功能,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。具体内容如下布局:<?xml version=&quo

这篇文章主要介绍了Android怎么实现多线程断点续传功能,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。

具体内容如下

android怎么实现多线程断点续传功能

布局:

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="Http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin"> <TextView  android:text="下载进度"  android:layout_width="wrap_content"  android:layout_height="wrap_content"  android:layout_alignParentTop="true"  android:layout_alignParentLeft="true"  android:layout_alignParentStart="true"  android:layout_marginTop="15dp"  android:id="@+id/tv_progress" /> <Button  android:text="下载"  android:layout_width="wrap_content"  android:layout_height="wrap_content"  android:layout_below="@+id/firstBar"  android:layout_alignParentLeft="true"  android:layout_alignParentStart="true"  android:layout_marginTop="29dp"  android:id="@+id/bt" /> <Button  android:text="暂停"  android:layout_width="wrap_content"  android:layout_height="wrap_content"  android:layout_alignTop="@+id/bt"  android:layout_toRightOf="@+id/bt"  android:layout_toEndOf="@+id/bt"  android:layout_marginLeft="15dp"  android:layout_marginStart="15dp"  android:id="@+id/bt_pause" /> <Button  android:text="继续"  android:layout_width="wrap_content"  android:layout_height="wrap_content"  android:layout_alignBottom="@+id/bt_pause"  android:layout_toRightOf="@+id/bt_pause"  android:layout_toEndOf="@+id/bt_pause"  android:layout_marginLeft="18dp"  android:layout_marginStart="18dp"  android:id="@+id/bt_start" /> <ProgressBar  android:id="@+id/firstBar"  android:layout_width="fill_parent"  android:layout_height="wrap_content"    android:layout_below="@+id/tv_progress"  android:layout_alignParentLeft="true"  android:layout_alignParentStart="true"  android:layout_marginTop="21dp" /></RelativeLayout>

MainActivity :

import android.os.Bundle;import android.os.Environment;import android.support.v7.app.AppCompatActivity;import android.view.View;import android.widget.Button;import android.widget.ProgressBar;import android.widget.TextView;import android.widget.Toast;import butterknife.BindView;import butterknife.ButterKnife;import butterknife.OnClick;public class MainActivity extends AppCompatActivity { @BindView(R.id.firstBar) ProgressBar firstBar; @BindView(R.id.tv_progress) TextView tvprogress; @BindView(R.id.bt) Button bt; @BindView(R.id.bt_pause) Button btPause; @BindView(R.id.bt_start) Button btStart; //下载地址 private String loadUrl = "http://mirror.aarnet.edu.au/pub/TED-talks/911Mothers_2010W-480p.mp4"; //文件缓存路径 private String filePath = Environment.getExternalStorageDirectory() + "/" + "911Mothers.mp4"; DownLoadFile downLoadFile; @Override protected void onCreate(Bundle savedInstanceState) {  super.onCreate(savedInstanceState);  setContentView(R.layout.activity_main);  ButterKnife.bind(this);  downLoadFile = new DownLoadFile(this, loadUrl, filePath, 3);  downLoadFile.setOnDownLoadListener(new DownLoadFile.DownLoadListener() {   @Override   public void getProgress(int progress) {    tvprogress.setText("当前进度 :" + progress + " %");    //设置进度条进度    firstBar.setProgress(progress);    if (progress==100){     Toast.makeText(MainActivity.this, "下载完成", Toast.LENGTH_SHORT).show();    }   }   @Override   public void onComplete() {    Toast.makeText(MainActivity.this, "下载完成", Toast.LENGTH_SHORT).show();   }   @Override   public void onFailure() {    Toast.makeText(MainActivity.this, "下载失败", Toast.LENGTH_SHORT).show();   }  }); }  @OnClick({R.id.bt, R.id.bt_pause, R.id.bt_start}) public void onViewClicked(View view) {  switch (view.getId()) {   case R.id.bt:    downLoadFile.downLoad();    break;   case R.id.bt_pause:    downLoadFile.onPause();    break;   case R.id.bt_start:    downLoadFile.onStart();    break;  } } @Override protected void onDestroy() {  downLoadFile.onDestroy();  super.onDestroy(); }}

DownLoadFile:

import android.content.Context;import android.content.SharedPreferences;import android.os.Handler;import android.os.Message;import java.io.InputStream;import java.io.RandoMaccessFile;import java.net.HttpURLConnection;import java.net.URL;public class DownLoadFile { private static final String SP_NAME = "download_file"; private static final String CURR_LENGTH = "curr_length"; private static final int DEFAULT_THREAD_COUNT = 4;//默认下载线程数 //以下为线程状态 private static final String DOWNLOAD_INIT = "1"; //初始化 private static final String DOWNLOAD_ING = "2";  //正在下载 private static final String DOWNLOAD_PAUSE = "3"; //暂停 private Context mContext; private String loadUrl;//网络获取的url private String filePath;//下载到本地的path private int threadCount = DEFAULT_THREAD_COUNT;//下载线程数 private int fileLength;//文件总大小 //使用volatile防止多线程不安全 private volatile int currLength;//当前总共下载的大小 private volatile int runningThreadCount;//正在运行的线程数 private Thread[] mThreads; private String stateDownload = DOWNLOAD_INIT;//当前线程状态 //下载进度监听 private DownLoadListener mDownLoadListener; public void setOnDownLoadListener(DownLoadListener mDownLoadListener) {  this.mDownLoadListener = mDownLoadListener; } //定义一个下载监听的接口 public interface DownLoadListener {  //返回当前下载进度的百分比  void getProgress(int progress);  //下载完成  void onComplete();  //下载失败  void onFailure(); }  public DownLoadFile(Context mContext, String loadUrl, String filePath) {  this(mContext, loadUrl, filePath, DEFAULT_THREAD_COUNT, null); } public DownLoadFile(Context mContext, String loadUrl, String filePath, DownLoadListener mDownLoadListener) {  this(mContext, loadUrl, filePath, DEFAULT_THREAD_COUNT, mDownLoadListener); } public DownLoadFile(Context mContext, String loadUrl, String filePath, int threadCount) {  this(mContext, loadUrl, filePath, threadCount, null); } public DownLoadFile(Context mContext, String loadUrl, String filePath, int threadCount, DownLoadListener mDownLoadListener) {  this.mContext = mContext;  this.loadUrl = loadUrl;  this.filePath = filePath;  this.threadCount = threadCount;  runningThreadCount = 0;  this.mDownLoadListener = mDownLoadListener; }  protected void downLoad() {  //在线程中运行,防止anr  new Thread(new Runnable() {   @Override   public void run() {    try {     //初始化数据     if (mThreads == null)      mThreads = new Thread[threadCount];     //建立连接请求     URL url = new URL(loadUrl);     HttpURLConnection conn = (HttpURLConnection) url.openConnection();     conn.setConnectTimeout(5000);     conn.setRequestMethod("GET");     int code = conn.getResponseCode();//获取返回码     if (code == 200) {//请求成功,根据文件大小开始分多线程下载      fileLength = conn.getContentLength();      //根据文件大小,先创建一个空文件      //“r“——以只读方式打开。调用结果对象的任何 write 方法都将导致抛出 IOException。      //“rw“——打开以便读取和写入。如果该文件尚不存在,则尝试创建该文件。      //“rws“—— 打开以便读取和写入,对于 “rw”,还要求对文件的内容或元数据的每个更新都同步写入到底层存储设备。      //“rwd“——打开以便读取和写入,对于 “rw”,还要求对文件内容的每个更新都同步写入到底层存储设备。      RandomAccessFile raf = new RandomAccessFile(filePath, "rwd");      raf.setLength(fileLength);      raf.close();      //计算各个线程下载的数据段      int blockLength = fileLength / threadCount;      SharedPreferences sp = mContext.getSharedPreferences(SP_NAME, Context.MODE_PRIVATE);      //获取上次取消下载的进度,若没有则返回0      currLength = sp.getInt(CURR_LENGTH, 0);      for (int i = 0; i < threadCount; i++) {       //开始位置,获取上次取消下载的进度,默认返回i*blockLength,即第i个线程开始下载的位置       int startPosition = sp.getInt(SP_NAME + (i + 1), i * blockLength);       //结束位置,-1是为了防止上一个线程和下一个线程重复下载衔接处数据       int endPosition = (i + 1) * blockLength - 1;       //将最后一个线程结束位置扩大,防止文件下载不完全,大了不影响,小了文件失效       if ((i + 1) == threadCount)        endPosition = endPosition * 2;       mThreads[i] = new DownThread(i + 1, startPosition, endPosition);       mThreads[i].start();      }     } else {      handler.sendEmptyMessage(FAILURE);     }    } catch (Exception e) {     e.printStackTrace();     handler.sendEmptyMessage(FAILURE);    }   }  }).start(); }  protected void cancel() {  if (mThreads != null) {   //若线程处于等待状态,则while循环处于阻塞状态,无法跳出循环,必须先唤醒线程,才能执行取消任务   if (stateDownload.equals(DOWNLOAD_PAUSE))    onStart();   for (Thread dt : mThreads) {    ((DownThread) dt).cancel();   }  } }  protected void onPause() {  if (mThreads != null)   stateDownload = DOWNLOAD_PAUSE; }  protected void onStart() {  if (mThreads != null)   synchronized (DOWNLOAD_PAUSE) {    stateDownload = DOWNLOAD_ING;    DOWNLOAD_PAUSE.notifyAll();   } } protected void onDestroy() {  if (mThreads != null)   mThreads = null; } private class DownThread extends Thread {  private boolean isGoOn = true;//是否继续下载  private int threadId;  private int startPosition;//开始下载点  private int endPosition;//结束下载点  private int currPosition;//当前线程的下载进度  private DownThread(int threadId, int startPosition, int endPosition) {   this.threadId = threadId;   this.startPosition = startPosition;   currPosition = startPosition;   this.endPosition = endPosition;   runningThreadCount++;  }  @Override  public void run() {   SharedPreferences sp = mContext.getSharedPreferences(SP_NAME, Context.MODE_PRIVATE);   try {    URL url = new URL(loadUrl);    HttpURLConnection conn = (HttpURLConnection) url.openConnection();    conn.setRequestMethod("GET");    conn.setRequestProperty("Range", "bytes=" + startPosition + "-" + endPosition);    conn.setConnectTimeout(5000);    //若请求头加上Range这个参数,则返回状态码为206,而不是200    if (conn.getResponseCode() == 206) {     InputStream is = conn.getInputStream();     RandomAccessFile raf = new RandomAccessFile(filePath, "rwd");     raf.seek(startPosition);//跳到指定位置开始写数据     int len;     byte[] buffer = new byte[1024];     while ((len = is.read(buffer)) != -1) {      //是否继续下载      if (!isGoOn)       break;      //回调当前进度      if (mDownLoadListener != null) {       currLength += len;       int progress = (int) ((float) currLength / (float) fileLength * 100);       handler.sendEmptyMessage(progress);      }      raf.write(buffer, 0, len);      //写完后将当前指针后移,为取消下载时保存当前进度做准备      currPosition += len;      synchronized (DOWNLOAD_PAUSE) {       if (stateDownload.equals(DOWNLOAD_PAUSE)) {        DOWNLOAD_PAUSE.wait();       }      }     }     is.close();     raf.close();     //线程计数器-1     runningThreadCount--;     //若取消下载,则直接返回     if (!isGoOn) {      //此处采用SharedPreferences保存每个线程的当前进度,和三个线程的总下载进度      if (currPosition < endPosition) {       sp.edit().putInt(SP_NAME + threadId, currPosition).apply();       sp.edit().putInt(CURR_LENGTH, currLength).apply();      }      return;     }     if (runningThreadCount == 0) {      sp.edit().clear().apply();      handler.sendEmptyMessage(SUCCESS);      handler.sendEmptyMessage(100);      mThreads = null;     }    } else {     sp.edit().clear().apply();     handler.sendEmptyMessage(FAILURE);    }   } catch (Exception e) {    sp.edit().clear().apply();    e.printStackTrace();    handler.sendEmptyMessage(FAILURE);   }  }  public void cancel() {   isGoOn = false;  } } //请求成功 private final int SUCCESS = 0x00000101; //请求失败 private final int FAILURE = 0x00000102; private Handler handler = new Handler() {  @Override  public void handleMessage(Message msg) {   if (mDownLoadListener != null) {    if (msg.what == SUCCESS) {     mDownLoadListener.onComplete();    } else if (msg.what == FAILURE) {     mDownLoadListener.onFailure();    } else {     mDownLoadListener.getProgress(msg.what);    }   }  } };}

感谢你能够认真阅读完这篇文章,希望小编分享的“android怎么实现多线程断点续传功能”这篇文章对大家有帮助,同时也希望大家多多支持编程网,关注编程网精选频道,更多相关知识等着你来学习!

--结束END--

本文标题: android怎么实现多线程断点续传功能

本文链接: https://www.lsjlt.com/news/220059.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • android怎么实现多线程断点续传功能
    这篇文章主要介绍了android怎么实现多线程断点续传功能,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。具体内容如下布局:<xml version="...
    99+
    2023-05-30
    android 多线程
  • android原生实现多线程断点续传功能
    本文实例为大家分享了android实现多线程断点续传功能的具体代码,供大家参考,具体内容如下 需求描述: 输入一个下载地址,和要启动的线程数量,点击下载 利用多线程将文件下载到手机端...
    99+
    2024-04-02
  • Android实现多线程断点续传
    本文实例为大家分享了Android实现多线程断点续传的具体代码,供大家参考,具体内容如下 多线程下载涉及到的知识点: 1、Service的使用:我们在Service中去下载文件;2、...
    99+
    2024-04-02
  • Android实现断点续传功能
    本文实例为大家分享了Android实现断点续传的具体代码,供大家参考,具体内容如下 断点续传功能,在文件上传中断时,下次上传同一文件时,能在上次的断点处继续上传,可节省时间和流量 总...
    99+
    2024-04-02
  • 怎么在Android中实现一个多线程断点续传下载功能
    本篇文章给大家分享的是有关怎么在Android中实现一个多线程断点续传下载功能,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。1、布局实现具体布局内容如下:<LinearL...
    99+
    2023-05-30
    android
  • Android中怎么利用FTP实现多线程断点续传下载上传功能
    Android中怎么利用FTP实现多线程断点续传下载上传功能,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。FTP下载原理FTP单线程断点续传FTP和传统的HTT...
    99+
    2023-05-30
    android
  • 怎么在Android中利用多线程实现一个断点续传下载功能
    怎么在Android中利用多线程实现一个断点续传下载功能?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。原理其实断点续传的原理很简单,从字面上理解,所谓断点续传就是从停止的地方重...
    99+
    2023-05-31
    android 多线程 roi
  • 怎么在Android应用中实现一个网络多线程断点续传下载功能
    怎么在Android应用中实现一个网络多线程断点续传下载功能?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。原理多线程下载的原理就是将要下载的文件分成若干份,其中...
    99+
    2023-05-31
    android 断点续传 多线程
  • Golang实现断点续传功能
    本文实例为大家分享了Golang实现断点续传的具体代码,供大家参考,具体内容如下 1、将文件pic_src.jpg复制到pic_des.jpg文件; 2、读写过程中断时,读写的中断位...
    99+
    2024-04-02
  • Java中怎么实现断点续传功能
    这篇文章给大家介绍Java中怎么实现断点续传功能,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。(一)断点续传的原理   其实断点续传的原理很简单,就是在Http的请求上和一般的下载有所不同而已。   打个比方,浏览器请...
    99+
    2023-06-03
  • C#中怎么实现断点续传功能
    本篇文章为大家展示了C#中怎么实现断点续传功能,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。以下是一个请求报文与相应的回复报文的例子:GET /image/index_r4_c1.jpg&...
    99+
    2023-06-17
  • Java实现多线程下载和断点续传
    java的多线程下载能够明显提升下载的速度,平时我们用的迅雷软件之所以能够下载那么快,就是使用了多线程;当用户在下载的过程中,有断电或断网的可能,当用户再次点击下载时,应该让用户接着...
    99+
    2024-04-02
  • java实现多线程文件的断点续传
    java文件的多线程断点续传大致原理,供大家参考,具体内容如下 谈到文件断点续传那么就离不开java.io.RandomAcessFile HttpUrlConnection类 大致...
    99+
    2024-04-02
  • Android入门之利用OKHttp实现断点续传功能
    目录简介课程目标断点下载的原理自定义Android里的ProgressBar的样式项目结构前端代码后端代码DbOpeerateHelper.javaDBService.javaDow...
    99+
    2023-01-09
    Android OKHttp断点续传功能 Android OKHttp断点续传 Android 断点续传 Android OKHttp
  • 怎么通过Java实现文件断点续传功能
    这篇文章主要介绍“怎么通过Java实现文件断点续传功能”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“怎么通过Java实现文件断点续传功能”文章能帮助大家解决问题。什么是断点续传用户上传大文件,网络差...
    99+
    2023-06-30
  • Android实现多线程断点下载
    目录QDownload1、如何使用1.1、导入依赖1.2、初始化下载组件1.3、核心控制器DownloadManager1.4、监听下载进度1.5、下载相关的操作1.6、应用市场ap...
    99+
    2024-04-02
  • HTML5如何实现文件断点续传功能
    这篇文章主要为大家展示了“HTML5如何实现文件断点续传功能”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“HTML5如何实现文件断点续传功能”这篇文章吧。HTM...
    99+
    2024-04-02
  • 通过Java实现文件断点续传功能
    目录什么是断点续传解决方案效果演示参考代码前端后端什么是断点续传 用户上传大文件,网络差点的需要历时数小时,万一线路中断,不具备断点续传的服务器就只能从头重传,而断点续传就是,允许用...
    99+
    2024-04-02
  • Java实现断点续传功能的示例代码
    目录一、题目描述二、解题思路三、代码详解一、题目描述 题目实现:网络资源的断点续传功能。 二、解题思路 获取要下载的资源网址 显示网络资源的大小 上次读取到的字节位置以及未读取的字节...
    99+
    2022-11-13
    Java实现断点续传 Java断点续传
  • Android如何实现简单断点续传和下载到本地功能
    这篇文章主要介绍了Android如何实现简单断点续传和下载到本地功能,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。具体内容如下效果展示导入依赖与权限依赖compile&nbs...
    99+
    2023-05-30
    android
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作