• android多线程断点续传下载文件


    一、目标

    1.多线程抢占服务器资源下载。

    2.断点续传。

    二、实现思路。

    假设分为三个线程:

    1.各个线程分别向服务器请求文件的不同部分。 这个涉及Http协议,可以在Header中使用Range参数设置向服务器请求文件的范围。

    2.文件部分的合并。

    2.1RandomAccessFile(随机读写文件类)。

    2.2分别写三个文件,最后合并。

    三、编码实现

    这里使用RandomAcessFile来实现,首先实现了多线程下载。



    public class MainActivity extends AppCompatActivity
    implements View.OnClickListener {
    int i = 0;
    private int progress = 0;
    android.os.Handler mHandler;

    @Override protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);
    final ProgressBar bar = (ProgressBar) findViewById(R.id.progressBar);
    Button downBtn = (Button) findViewById(R.id.button);
    final EditText tcEt= (EditText) findViewById(R.id.editText2);
    Button restartBtn= (Button) findViewById(R.id.button2);
    restartBtn.setOnClickListener(this);
    final EditText urlEdit = (EditText) findViewById(R.id.editText);
    downBtn.setOnClickListener(new View.OnClickListener() {
    @Override public void onClick(View v) {
    new Thread() {
    @Override public void run() {
    try {
    URL url = new URL(urlEdit.getText().toString());
    HttpURLConnection connection
    = (HttpURLConnection) url.openConnection();
    connection.setRequestMethod("GET");
    connection.setConnectTimeout(5000);
    int length = connection.getContentLength();
    Log.i("xiahong","size:"+length);
    if (length < 0) {
    return;
    }
    bar.setMax(length);
    File file = new File(
    Environment.getExternalStorageDirectory()
    .toString(), "donw.fiel");
    RandomAccessFile randomAccessFile
    = new RandomAccessFile(file, "rw");
    randomAccessFile.setLength(length);
    int conut=Integer.valueOf(tcEt.getText().toString());
    int blockSize = length / conut;
    for (int i = 0; i < conut; i++) {
    int begin = i * blockSize;
    int end = (i + 1) * blockSize;
    if (i == conut-1) {
    end = length;
    }
    //Create Thread to Download File
    Runnable runnable= new DownloadRunable(begin,
    end,file,
    url,i) ;

    new Thread(runnable).start();
    }
    } catch (MalformedURLException e) {
    e.printStackTrace();
    } catch (IOException e) {
    e.printStackTrace();
    }
    }
    }.start();
    }
    });
    mHandler=new android.os.Handler(){
    @Override public void handleMessage(Message msg) {
    bar.setProgress(progress);
    }
    };
    }


    @Override public void onClick(View v) {
    Intent intent=getBaseContext().getPackageManager()
    .getLaunchIntentForPackage(getBaseContext().getPackageName());;
    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    startActivity(intent);

    }

      //文件下载类
    class DownloadRunable implements Runnable {
    private int begin;
    private int end;
    private File mFile;
    private URL mURL;
    private int id;


    public DownloadRunable(int begin, int end, File mFile, URL mURL, int id) {
    this.begin = begin;
    this.end = end;
    this.mFile = mFile;
    this.mURL = mURL;
    this.id = id;
    }


    @Override public void run() {
    try {
    HttpURLConnection connection
    = (HttpURLConnection) mURL.openConnection();
    connection.setRequestMethod("GET");
    connection.setReadTimeout(5000);
    connection.setRequestProperty("Range",
    "bytes=" + begin + "-" + end);//向服务器请求文件范围。

    InputStream is = connection.getInputStream();
    byte[] bs = new byte[1024 * 1024];
    RandomAccessFile randomAccessFile =
    new RandomAccessFile(mFile, "rw");
    randomAccessFile.seek(begin);

    int length = 0;
    while ((length = is.read(bs)) != -1) {
    randomAccessFile.write(bs, 0, length);
    updateProgress(length);
    }
    is.close();
    randomAccessFile.close();
    } catch (IOException e) {
    e.printStackTrace();
    }
    }


    synchronized void updateProgress(int len) {
    progress += len;
    mHandler.sendEmptyMessage(0);
    }
    }
    }

    下面实现断点续传。
    实现思路就是将线程中耗时的循环操作加上一个Boolean类型的Flag标志,每次下载时将下载的进度保存到一个队列中,
    在需要回复的时候重新创建线程,读取已保存的列表进行下载,即可。

  • 相关阅读:
    touch:创建文件及修改文件时间戳
    stat:查看文件时间参数
    获取二维数组里面实际存有数据的行数
    Math.Atan2 方法
    c#移位运算符("<<"及">>")
    c# 一维数组和二维数组的几种定义方式<转>
    C#异常处理总结
    C#图片灰度处理(位深度24→位深度8)、C#图片二值化处理(位深度8→位深度1)
    WinForm窗体及其控件的自适应
    C#的WinForm窗体美化
  • 原文地址:https://www.cnblogs.com/lzh-Linux/p/5089292.html
Copyright © 2020-2023  润新知