亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 系統 > Android > 正文

Android實現多線程下載文件的方法

2020-04-11 11:23:05
字體:
來源:轉載
供稿:網友

本文實例講述了Android實現多線程下載文件的方法。分享給大家供大家參考。具體如下:

多線程下載大概思路就是通過Range 屬性實現文件分段,然后用RandomAccessFile 來讀寫文件,最終合并為一個文件

首先看下效果圖:

創建工程 ThreadDemo

首先布局文件 threaddemo.xml

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"   android:orientation="vertical"   android:layout_width="fill_parent"   android:layout_height="fill_parent"   > <TextView    android:layout_width="fill_parent"    android:layout_height="wrap_content"    android:text="下載地址"   /> <TextView   android:id="@+id/downloadurl"   android:layout_width="fill_parent"    android:layout_height="wrap_content"    android:lines="5"   /> <TextView    android:layout_width="fill_parent"    android:layout_height="wrap_content"    android:text="線程數"   /> <EditText   android:id="@+id/downloadnum"   android:layout_width="fill_parent"    android:layout_height="wrap_content"    /> <ProgressBar   android:id="@+id/downloadProgressBar"   android:layout_width="fill_parent"    style="?android:attr/progressBarStyleHorizontal"   android:layout_height="wrap_content"    /> <TextView   android:id="@+id/downloadinfo"   android:layout_width="fill_parent"    android:layout_height="wrap_content"    android:text="下載進度 0"   /> <Button   android:id="@+id/downloadbutton"   android:layout_width="wrap_content"    android:layout_height="wrap_content"    android:text="開始下載"   /> </LinearLayout>
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  android:orientation="vertical" android:layout_width="fill_parent"  android:layout_height="fill_parent"  ><TextView   android:layout_width="fill_parent"   android:layout_height="wrap_content" android:text="下載地址"  /><TextViewandroid:id="@+id/downloadurl"android:layout_width="fill_parent" android:layout_height="wrap_content" android:lines="5"/><TextView   android:layout_width="fill_parent"   android:layout_height="wrap_content" android:text="線程數"  /><EditTextandroid:id="@+id/downloadnum"android:layout_width="fill_parent" android:layout_height="wrap_content" /><ProgressBarandroid:id="@+id/downloadProgressBar"android:layout_width="fill_parent" style="?android:attr/progressBarStyleHorizontal"  android:layout_height="wrap_content" /><TextViewandroid:id="@+id/downloadinfo"android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="下載進度 0"/><Buttonandroid:id="@+id/downloadbutton"android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="開始下載"/></LinearLayout> 

主界面 Acitivity

public class ThreadDownloadDemo extends Activity {   private TextView downloadurl;   private EditText downloadnum;   private Button downloadbutton;   private ProgressBar downloadProgressBar;   private TextView downloadinfo;   private int downloadedSize = 0;   private int fileSize = 0;   private long downloadtime;   @Override   public void onCreate(Bundle savedInstanceState) {     super.onCreate(savedInstanceState);     setContentView(R.layout.threaddemo);     downloadurl = (TextView) findViewById(R.id.downloadurl);     downloadurl.setText("http://file16.top100.cn/201105110911/AA5CC27CBE34DEB50A194581D1300881/Special_323149/%E8%8D%B7%E5%A1%98%E6%9C%88%E8%89%B2.mp3");     downloadnum = (EditText) findViewById(R.id.downloadnum);     downloadinfo = (TextView) findViewById(R.id.downloadinfo);     downloadbutton = (Button) findViewById(R.id.downloadbutton);     downloadProgressBar = (ProgressBar) findViewById(R.id.downloadProgressBar);     downloadProgressBar.setVisibility(View.VISIBLE);     downloadProgressBar.setMax(100);     downloadProgressBar.setProgress(0);     downloadbutton.setOnClickListener(new OnClickListener() {       public void onClick(View v) {         download();         downloadtime = SystemClock.currentThreadTimeMillis();       }     });   }   private void download() {     // 獲取SD卡目錄      String dowloadDir = Environment.getExternalStorageDirectory()         + "/threaddemodownload/";     File file = new File(dowloadDir);     //創建下載目錄      if (!file.exists()) {       file.mkdirs();     }     //讀取下載線程數,如果為空,則單線程下載      int downloadTN = Integer.valueOf("".equals(downloadnum.getText()         .toString()) ? "1" : downloadnum.getText().toString());     String fileName = "hetang.mp3";     //開始下載前把下載按鈕設置為不可用      downloadbutton.setClickable(false);     //進度條設為0      downloadProgressBar.setProgress(0);     //啟動文件下載線程      new downloadTask("http://file16.top100.cn/201105110911/AA5CC27CBE34DEB50A194581D1300881/Special_323149/%E8%8D%B7%E5%A1%98%E6%9C%88%E8%89%B2.mp3", Integer         .valueOf(downloadTN), dowloadDir + fileName).start();   }   Handler handler = new Handler() {     @Override     public void handleMessage(Message msg) {       //當收到更新視圖消息時,計算已完成下載百分比,同時更新進度條信息        int progress = (Double.valueOf((downloadedSize * 1.0 / fileSize * 100))).intValue();       if (progress == 100) {         downloadbutton.setClickable(true);         downloadinfo.setText("下載完成!");         Dialog mdialog = new AlertDialog.Builder(ThreadDownloadDemo.this)           .setTitle("提示信息")           .setMessage("下載完成,總用時為:"+(SystemClock.currentThreadTimeMillis()-downloadtime)+"毫秒")           .setNegativeButton("確定", new DialogInterface.OnClickListener(){             @Override             public void onClick(DialogInterface dialog, int which) {               dialog.dismiss();             }           })           .create();         mdialog.show();       } else {         downloadinfo.setText("當前進度:" + progress + "%");       }       downloadProgressBar.setProgress(progress);     }   };   public class downloadTask extends Thread {     private int blockSize, downloadSizeMore;     private int threadNum = 5;     String urlStr, threadNo, fileName;     public downloadTask(String urlStr, int threadNum, String fileName) {       this.urlStr = urlStr;       this.threadNum = threadNum;       this.fileName = fileName;     }     @Override     public void run() {       FileDownloadThread[] fds = new FileDownloadThread[threadNum];       try {         URL url = new URL(urlStr);         URLConnection conn = url.openConnection();         //防止返回-1          InputStream in = conn.getInputStream();         //獲取下載文件的總大小          fileSize = conn.getContentLength();         Log.i("bb", "======================fileSize:"+fileSize);         //計算每個線程要下載的數據量          blockSize = fileSize / threadNum;         // 解決整除后百分比計算誤差          downloadSizeMore = (fileSize % threadNum);         File file = new File(fileName);         for (int i = 0; i < threadNum; i++) {           Log.i("bb", "======================i:"+i);           //啟動線程,分別下載自己需要下載的部分            FileDownloadThread fdt = new FileDownloadThread(url, file, i * blockSize, (i + 1) * blockSize - 1);           fdt.setName("Thread" + i);           fdt.start();           fds[i] = fdt;         }         boolean finished = false;         while (!finished) {           // 先把整除的余數搞定            downloadedSize = downloadSizeMore;           finished = true;           for (int i = 0; i < fds.length; i++) {             downloadedSize += fds[i].getDownloadSize();             if (!fds[i].isFinished()) {               finished = false;             }           }           handler.sendEmptyMessage(0);           //線程暫停一秒            sleep(1000);         }       } catch (Exception e) {         e.printStackTrace();       }     }   } } public class ThreadDownloadDemo extends Activity {private TextView downloadurl;private EditText downloadnum;private Button downloadbutton;private ProgressBar downloadProgressBar;private TextView downloadinfo;private int downloadedSize = 0;private int fileSize = 0;private long downloadtime;@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.threaddemo);downloadurl = (TextView) findViewById(R.id.downloadurl);downloadurl.setText("http://file16.top100.cn/201105110911/AA5CC27CBE34DEB50A194581D1300881/Special_323149/%E8%8D%B7%E5%A1%98%E6%9C%88%E8%89%B2.mp3");downloadnum = (EditText) findViewById(R.id.downloadnum);downloadinfo = (TextView) findViewById(R.id.downloadinfo);downloadbutton = (Button) findViewById(R.id.downloadbutton);downloadProgressBar = (ProgressBar) findViewById(R.id.downloadProgressBar);downloadProgressBar.setVisibility(View.VISIBLE);downloadProgressBar.setMax(100);downloadProgressBar.setProgress(0);downloadbutton.setOnClickListener(new OnClickListener() {public void onClick(View v) {download();downloadtime = SystemClock.currentThreadTimeMillis();}});}private void download() {// 獲取SD卡目錄String dowloadDir = Environment.getExternalStorageDirectory()+ "/threaddemodownload/";File file = new File(dowloadDir);//創建下載目錄if (!file.exists()) {file.mkdirs();}//讀取下載線程數,如果為空,則單線程下載int downloadTN = Integer.valueOf("".equals(downloadnum.getText().toString()) ? "1" : downloadnum.getText().toString());String fileName = "hetang.mp3";//開始下載前把下載按鈕設置為不可用downloadbutton.setClickable(false);//進度條設為0downloadProgressBar.setProgress(0);//啟動文件下載線程new downloadTask("http://file16.top100.cn/201105110911/AA5CC27CBE34DEB50A194581D1300881/Special_323149/%E8%8D%B7%E5%A1%98%E6%9C%88%E8%89%B2.mp3", Integer.valueOf(downloadTN), dowloadDir + fileName).start();}Handler handler = new Handler() {@Overridepublic void handleMessage(Message msg) {//當收到更新視圖消息時,計算已完成下載百分比,同時更新進度條信息int progress = (Double.valueOf((downloadedSize * 1.0 / fileSize * 100))).intValue();if (progress == 100) {downloadbutton.setClickable(true);downloadinfo.setText("下載完成!");Dialog mdialog = new AlertDialog.Builder(ThreadDownloadDemo.this).setTitle("提示信息").setMessage("下載完成,總用時為:"+(SystemClock.currentThreadTimeMillis()-downloadtime)+"毫秒").setNegativeButton("確定", new DialogInterface.OnClickListener(){@Overridepublic void onClick(DialogInterface dialog, int which) {dialog.dismiss();}}).create();mdialog.show();} else {downloadinfo.setText("當前進度:" + progress + "%");}downloadProgressBar.setProgress(progress);}}; public class downloadTask extends Thread {private int blockSize, downloadSizeMore;private int threadNum = 5;String urlStr, threadNo, fileName;public downloadTask(String urlStr, int threadNum, String fileName) {this.urlStr = urlStr;this.threadNum = threadNum;this.fileName = fileName;}@Overridepublic void run() {FileDownloadThread[] fds = new FileDownloadThread[threadNum];try {URL url = new URL(urlStr);URLConnection conn = url.openConnection();//防止返回-1InputStream in = conn.getInputStream();//獲取下載文件的總大小fileSize = conn.getContentLength();Log.i("bb", "======================fileSize:"+fileSize);//計算每個線程要下載的數據量blockSize = fileSize / threadNum;// 解決整除后百分比計算誤差downloadSizeMore = (fileSize % threadNum);File file = new File(fileName);for (int i = 0; i < threadNum; i++) {Log.i("bb", "======================i:"+i);//啟動線程,分別下載自己需要下載的部分FileDownloadThread fdt = new FileDownloadThread(url, file, i * blockSize, (i + 1) * blockSize - 1);fdt.setName("Thread" + i);fdt.start();fds[i] = fdt;}boolean finished = false;while (!finished) {// 先把整除的余數搞定downloadedSize = downloadSizeMore;finished = true;for (int i = 0; i < fds.length; i++) {downloadedSize += fds[i].getDownloadSize();if (!fds[i].isFinished()) {finished = false;}}handler.sendEmptyMessage(0);//線程暫停一秒sleep(1000);}}catch (Exception e) {e.printStackTrace();}}}} 

這里啟動線程將文件分割為幾個部分,每一個部分再啟動一個線程去下載數據
下載文件的線程

public class FileDownloadThread extends Thread{   private static final int BUFFER_SIZE=1024;   private URL url;   private File file;   private int startPosition;   private int endPosition;   private int curPosition;   //標識當前線程是否下載完成    private boolean finished=false;   private int downloadSize=0;   public FileDownloadThread(URL url,File file,int startPosition,int endPosition){     this.url=url;     this.file=file;     this.startPosition=startPosition;     this.curPosition=startPosition;     this.endPosition=endPosition;   }   @Override   public void run() {     BufferedInputStream bis = null;     RandomAccessFile fos = null;                             byte[] buf = new byte[BUFFER_SIZE];     URLConnection con = null;     try {       con = url.openConnection();       con.setAllowUserInteraction(true);       //設置當前線程下載的起止點        con.setRequestProperty("Range", "bytes=" + startPosition + "-" + endPosition);       Log.i("bb", Thread.currentThread().getName()+" bytes=" + startPosition + "-" + endPosition);       //使用java中的RandomAccessFile 對文件進行隨機讀寫操作        fos = new RandomAccessFile(file, "rw");       //設置寫文件的起始位置        fos.seek(startPosition);       bis = new BufferedInputStream(con.getInputStream());        //開始循環以流的形式讀寫文件        while (curPosition < endPosition) {         int len = bis.read(buf, 0, BUFFER_SIZE);                 if (len == -1) {           break;         }         fos.write(buf, 0, len);         curPosition = curPosition + len;         if (curPosition > endPosition) {           downloadSize+=len - (curPosition - endPosition) + 1;         } else {           downloadSize+=len;         }       }       //下載完成設為true        this.finished = true;       bis.close();       fos.close();     } catch (IOException e) {       e.printStackTrace();     }   }   public boolean isFinished(){     return finished;   }   public int getDownloadSize() {     return downloadSize;   } } public class FileDownloadThread extends Thread{private static final int BUFFER_SIZE=1024;private URL url;private File file;private int startPosition;private int endPosition;private int curPosition;//標識當前線程是否下載完成private boolean finished=false;private int downloadSize=0;public FileDownloadThread(URL url,File file,int startPosition,int endPosition){this.url=url;this.file=file;this.startPosition=startPosition;this.curPosition=startPosition;this.endPosition=endPosition;}@Overridepublic void run() {BufferedInputStream bis = null;RandomAccessFile fos = null;byte[] buf = new byte[BUFFER_SIZE];URLConnection con = null;try {con = url.openConnection();con.setAllowUserInteraction(true);//設置當前線程下載的起止點con.setRequestProperty("Range", "bytes=" + startPosition + "-" + endPosition);Log.i("bb", Thread.currentThread().getName()+" bytes=" + startPosition + "-" + endPosition);//使用java中的RandomAccessFile 對文件進行隨機讀寫操作fos = new RandomAccessFile(file, "rw");//設置寫文件的起始位置fos.seek(startPosition);bis = new BufferedInputStream(con.getInputStream());//開始循環以流的形式讀寫文件while (curPosition < endPosition) {int len = bis.read(buf, 0, BUFFER_SIZE);if (len == -1) {break;}fos.write(buf, 0, len);curPosition = curPosition + len;if (curPosition > endPosition) {downloadSize+=len - (curPosition - endPosition) + 1;} else {downloadSize+=len;}}//下載完成設為truethis.finished = true;bis.close();fos.close();} catch (IOException e) {e.printStackTrace();}}public boolean isFinished(){return finished;}public int getDownloadSize() {return downloadSize;}}

這里通過RandomAccessFile 的seek方法定位到相應的位置 并實時記錄下載量
當然這里需要聯網和訪問SD卡 所以要加上相應的權限

<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission> <uses-permission android:name="android.permission.INTERNET" /><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>

這樣就OK了 下面可以看看斷點續傳的問題了。有待測試~~

希望本文所述對大家的Android程序設計有所幫助。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产精品99久久久久久白浆小说| 国产一区二区日韩精品欧美精品| 2019中文字幕免费视频| 亚洲国产精品999| 欧美午夜无遮挡| 国产成人亚洲综合青青| 91亚洲va在线va天堂va国| 夜夜嗨av一区二区三区四区| 色偷偷噜噜噜亚洲男人| 亚洲激情视频在线播放| 青青久久av北条麻妃海外网| 亚洲精品成人av| 81精品国产乱码久久久久久| 日韩视频免费中文字幕| 91精品国产综合久久香蕉| 韩剧1988在线观看免费完整版| 日韩福利视频在线观看| 亚洲图片欧美日产| 精品丝袜一区二区三区| 久久777国产线看观看精品| 欧美影院在线播放| 亚洲人成毛片在线播放| 国产福利成人在线| 九九热这里只有在线精品视| 精品一区二区三区三区| 97人人做人人爱| 一区二区三区视频在线| 国产一区二中文字幕在线看| 国产欧美一区二区三区四区| 伊人男人综合视频网| 日韩免费视频在线观看| 亚洲韩国日本中文字幕| 韩国19禁主播vip福利视频| 国产亚洲精品成人av久久ww| 成人有码在线视频| 国产女人18毛片水18精品| 欧美激情第6页| 亚洲黄在线观看| 国产成人免费91av在线| 欧美日韩在线视频观看| 欧美精品videos| 国产高清视频一区三区| 日韩在线视频播放| 啊v视频在线一区二区三区| 亚洲福利视频二区| 久久777国产线看观看精品| 日韩一二三在线视频播| 国产精品第一视频| 自拍偷拍亚洲精品| 8090理伦午夜在线电影| 欧美一级bbbbb性bbbb喷潮片| 亚洲欧美国产日韩天堂区| 色哟哟亚洲精品一区二区| 亚洲精品一区二区网址| 午夜精品久久久久久久久久久久久| 国产一区二区三区四区福利| 欧美视频一二三| 国产精品欧美风情| 在线日韩日本国产亚洲| 亚洲人在线视频| 国产精国产精品| 97av在线视频免费播放| 夜色77av精品影院| 欧美体内谢she精2性欧美| 欧美精品日韩www.p站| 亚洲大尺度美女在线| 国产美女直播视频一区| 亚洲精品久久久久中文字幕欢迎你| 一本色道久久88亚洲综合88| 欧美成人黑人xx视频免费观看| 国产精品免费久久久久影院| 久久久久久国产三级电影| 久久精品久久久久电影| 日本久久久久亚洲中字幕| 在线观看国产精品日韩av| 亚洲精品www久久久久久广东| 91大神在线播放精品| 91精品国产综合久久香蕉最新版| 国产精品视频自拍| 韩国视频理论视频久久| 日韩av综合中文字幕| 久久影视电视剧凤归四时歌| 亚洲精品免费一区二区三区| 亚洲福利视频二区| 欧美一级高清免费| 日韩女在线观看| 午夜精品在线观看| 国产乱肥老妇国产一区二| 欧洲美女7788成人免费视频| 久久精品视频在线播放| 欧美日韩午夜剧场| 欧美日韩在线一区| 亚洲mm色国产网站| 91精品国产高清久久久久久| 亚洲福利影片在线| 国产精品美女免费视频| 亚洲韩国日本中文字幕| 国产91精品最新在线播放| 亚洲综合社区网| 尤物九九久久国产精品的分类| 日韩欧美国产网站| 78m国产成人精品视频| 国产美女扒开尿口久久久| 国产精品国语对白| 欧美激情videoshd| 一区二区三区四区在线观看视频| 热99久久精品| 亚洲香蕉伊综合在人在线视看| 最近2019中文免费高清视频观看www99| 92版电视剧仙鹤神针在线观看| 久久精品国产成人精品| 久久99国产综合精品女同| 一区二区三区久久精品| 国产精品欧美在线| 国产不卡在线观看| 久久99热这里只有精品国产| 亚洲欧美日韩视频一区| 欧美一级视频一区二区| 欧美洲成人男女午夜视频| 亚洲美女中文字幕| 国产精品久久久久久av福利软件| 国产精品一区二区久久国产| 91夜夜揉人人捏人人添红杏| 国产精品va在线播放我和闺蜜| 91精品国产自产在线| 亚洲男人天堂久| 亚洲精品aⅴ中文字幕乱码| 一区二区三区在线播放欧美| 亚洲国产一区二区三区四区| 欧美一乱一性一交一视频| 成人在线观看视频网站| 欧美激情第一页xxx| 国产精品99久久久久久人| 亚洲欧美制服第一页| 97在线视频精品| 成人国产精品色哟哟| 欧美激情xxxx性bbbb| 青青久久av北条麻妃黑人| 成人国产精品久久久久久亚洲| 中文字幕免费精品一区| 国产一区二区三区丝袜| 91免费综合在线| 久久久久久久久久久成人| 亚洲精品狠狠操| 亚洲精品mp4| 欧美精品中文字幕一区| 国产欧美亚洲精品| 久久福利网址导航| 欧美丰满少妇xxxx| 2019最新中文字幕| 国内精品久久久久影院 日本资源| 97色在线观看| 亚洲一区二区免费在线| 日韩中文视频免费在线观看| 久久91精品国产| 亚洲欧美制服第一页| 欧美日韩高清在线观看| 欧美日韩国产区| 日韩大胆人体377p| 日本久久精品视频| 精品国产区一区二区三区在线观看| 国产激情视频一区| 亚洲精品福利在线观看| 中文字幕在线日韩|