[关闭]
@Tyhj 2017-02-24T08:50:34.000000Z 字数 4872 阅读 959

Android多线程断点续传

Android


多线程下载,

就是将服务器上的文件分为几段,然后去分段下载,然后用RandomAccessFile这个类将文件组合到一起。

断点续传

就是把已经下载的文件进度保存起来,再次下载的时候就继续下载。

具体代码:

  1. package demand.example.tyhj.download;
  2. import android.os.Bundle;
  3. import android.os.Environment;
  4. import android.os.Handler;
  5. import android.os.Message;
  6. import android.support.design.widget.FloatingActionButton;
  7. import android.support.design.widget.Snackbar;
  8. import android.support.v7.app.AppCompatActivity;
  9. import android.support.v7.widget.Toolbar;
  10. import android.util.Log;
  11. import android.view.View;
  12. import android.view.Menu;
  13. import android.view.MenuItem;
  14. import android.widget.Button;
  15. import android.widget.EditText;
  16. import android.widget.ProgressBar;
  17. import android.widget.Toast;
  18. import java.io.File;
  19. import java.io.IOException;
  20. import java.io.InputStream;
  21. import java.io.RandomAccessFile;
  22. import java.net.HttpURLConnection;
  23. import java.net.MalformedURLException;
  24. import java.net.URL;
  25. import java.net.URLConnection;
  26. import java.util.ArrayList;
  27. import java.util.HashMap;
  28. import java.util.List;
  29. public class MainActivity extends AppCompatActivity {
  30. EditText editText;
  31. Button button;
  32. ProgressBar progressBar;
  33. //文件长度
  34. private int leanth;
  35. //下载进度
  36. private int total = 0;
  37. //下载地址
  38. private URL url;
  39. //下载的文件
  40. private File file;
  41. //开始或者暂停下载
  42. private boolean downLoading;
  43. //用于保存下载线程(每段为一个线程)
  44. private List<HashMap<String, Integer>> threadList;
  45. @Override
  46. protected void onCreate(Bundle savedInstanceState) {
  47. super.onCreate(savedInstanceState);
  48. setContentView(R.layout.activity_main);
  49. threadList = new ArrayList<>();
  50. editText = (EditText) findViewById(R.id.fileUrl);
  51. button = (Button) findViewById(R.id.btn_download);
  52. progressBar = (ProgressBar) findViewById(R.id.progressBar);
  53. //editText.setText("http://192.168.31.215:8080/Download/downLoadFile/move.mp4");
  54. progressBar.setProgress(0);
  55. button.setOnClickListener(new View.OnClickListener() {
  56. @Override
  57. public void onClick(View view) {
  58. if (downLoading) {
  59. downLoading = false;
  60. button.setText("开始");
  61. return;
  62. }
  63. downLoading = true;
  64. button.setText("暂停");
  65. if (threadList.size() == 0) {
  66. //之前没有开始下载文件
  67. new Thread(new Runnable() {
  68. @Override
  69. public void run() {
  70. try {
  71. url = new URL(editText.getText().toString());
  72. HttpURLConnection connection = (HttpURLConnection) url.openConnection();
  73. connection.setRequestMethod("GET");
  74. connection.setConnectTimeout(500);
  75. //获取文件的大小
  76. leanth = connection.getContentLength();
  77. Log.e("开始长度:",leanth+"");
  78. //设置进度条的长度
  79. progressBar.setMax(leanth/1024);
  80. //文件不存在
  81. if (leanth < 0) {
  82. handler.obtainMessage(1, 0, 0).sendToTarget();
  83. return;
  84. }
  85. //保存文件地址
  86. file = new File(Environment.getExternalStorageDirectory(), getName(editText.getText().toString()));
  87. //设置分割下载的文件
  88. RandomAccessFile random = new RandomAccessFile(file, "rw");
  89. random.setLength(leanth);
  90. //分为三段下载
  91. int blockSize = leanth / 3;
  92. for (int i = 0; i < 3; i++) {
  93. int begin = i * blockSize;
  94. int end = (i + 1) * blockSize;
  95. if (i == 2)
  96. end = leanth;
  97. //设置每段下载的长度
  98. HashMap<String, Integer> map = new HashMap<String, Integer>();
  99. map.put("begin", begin);
  100. map.put("end", end);
  101. map.put("finished", 0);
  102. threadList.add(map);
  103. //创建线程下载文件
  104. Thread t = new Thread(new Download(begin, end, file, url, i));
  105. t.start();
  106. }
  107. } catch (MalformedURLException e) {
  108. Toast.makeText(MainActivity.this, "Url错误", Toast.LENGTH_SHORT).show();
  109. e.printStackTrace();
  110. } catch (IOException e) {
  111. e.printStackTrace();
  112. }
  113. }
  114. }).start();
  115. } else {
  116. //恢复下载
  117. for (int i = 0; i < threadList.size(); i++) {
  118. HashMap<String, Integer> map = threadList.get(i);
  119. int begin = map.get("begin");
  120. int end = map.get("end");
  121. int finished = map.get("finished");
  122. Thread t = new Thread(new Download(begin + finished, end, file, url, i));
  123. t.start();
  124. }
  125. }
  126. }
  127. });
  128. }
  129. //获取现在文件的名字
  130. private String getName(String url) {
  131. return url.substring(url.lastIndexOf("/") + 1, url.length());
  132. }
  133. //下载类
  134. class Download implements Runnable {
  135. private int begin;
  136. private int end;
  137. private File file;
  138. private URL url;
  139. private int id;
  140. public Download(int begin, int end, File file, URL url, int id) {
  141. this.begin = begin;
  142. this.end = end;
  143. this.file = file;
  144. this.url = url;
  145. this.id = id;
  146. }
  147. @Override
  148. public void run() {
  149. try {
  150. //判断是否下载完成
  151. if (begin > end)
  152. return;
  153. HttpURLConnection connection = (HttpURLConnection) url.openConnection();
  154. connection.setRequestMethod("GET");
  155. connection.setConnectTimeout(500);
  156. //设置需要下载的位置
  157. connection.setRequestProperty("Range", "bytes=" + begin + "-" + end);
  158. InputStream is = connection.getInputStream();
  159. byte[] buff = new byte[1024 * 1024];
  160. RandomAccessFile accessFile = new RandomAccessFile(file, "rw");
  161. //设置写入文件的位置
  162. accessFile.seek(begin);
  163. int len = 0;
  164. HashMap<String, Integer> map = threadList.get(id);
  165. //开始下载
  166. while ((len = is.read(buff)) != -1&&downLoading) {
  167. accessFile.write(buff, 0, len);
  168. //更新总下载进度
  169. updateProgress(len);
  170. //更新每段的下载进度
  171. map.put("finished", map.get("finished") + len);
  172. }
  173. is.close();
  174. accessFile.close();
  175. } catch (IOException e) {
  176. handler.sendEmptyMessage(1);
  177. e.printStackTrace();
  178. }
  179. }
  180. }
  181. //更新总下载进度
  182. synchronized private void updateProgress(int add) {
  183. total += add;
  184. handler.obtainMessage(0, total, 0).sendToTarget();
  185. }
  186. Handler handler = new Handler() {
  187. @Override
  188. public void handleMessage(Message msg) {
  189. super.handleMessage(msg);
  190. if (msg.what == 0) {
  191. //更新UI
  192. progressBar.setProgress(msg.arg1/1024);
  193. Log.e("长度:",msg.arg1+"");
  194. if (msg.arg1 >= leanth)
  195. Toast.makeText(MainActivity.this, "下载完成", Toast.LENGTH_SHORT).show();
  196. } else if (msg.what == 1) {
  197. Toast.makeText(MainActivity.this, "文件不存在", Toast.LENGTH_SHORT).show();
  198. downLoading = false;
  199. button.setText("开始");
  200. }
  201. }
  202. };
  203. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注