Android的斷點下載詳細分析一

來源:互聯網
上載者:User

Android的斷點下載詳細分析一

在Android中斷點下載用的很多,看了黎活明老師的教程之後,對斷點下載也有一定的認識,然後跟大家分享。

首先,斷點下載他的功能描述:使用者可以從網路上下載任意的資源,使用斷點下載的好處就是:當使用者由於一些其他的原因退出了本應用,但是此時正在下載者一些檔案,當使用者再次點進本應用的時候,我們不應該讓使用者重新下載該檔案,而是從上次下載完成的那個地方開始繼續下載,這就是斷點下載的功能。

實現思路:從網路下載資源,需要使用到HTTP協議(如果是資源比較大的建議使用socket,比如上百M的),需要使用到多線程,Android4.x之後不允許在UI線程訪問網路,所以我們需要使用多線程,或者是非同步任務,volley等其他,然後因為需要當使用者退出應用再進入的時候讀取原來的下載進度,因此我們需要使用到SQLite技術,用於儲存每一條線程的下載進度,每當用於再次進入的時候可以從資料庫讀取資料然後傳到線程那裡,從他以前停止下載的位置開始下載。

下面是一些源碼分析:

這是MainActivity.java

public class MainActivity extends Activity {/* * 下載路徑text */    private EditText pathText;/* * 下載結果顯示 */    private TextView resultView;/* * 點擊下載button */    private Button downloadButton;/* * 點擊停止button */    private Button stopbutton;/* * 顯示進度progressBar */    private ProgressBar progressBar;/* * hanlder的作用是用於往建立Hander對象所在的線程所綁定的訊息佇列發送訊息 * 這裡是UI線程的Handler,改變progressBar,resultText */    private Handler handler = new UIHander();        private final class UIHander extends Handler{public void handleMessage(Message msg) {switch (msg.what) {case 1:int size = msg.getData().getInt("size");progressBar.setProgress(size);float num = (float)progressBar.getProgress() / (float)progressBar.getMax();int result = (int)(num * 100);resultView.setText(result+ "%");//progressBar達到最大值,下載完成if(progressBar.getProgress() == progressBar.getMax()){Toast.makeText(getApplicationContext(), R.string.success, 1).show();}break;case -1://下載失敗Toast.makeText(getApplicationContext(), R.string.error, 1).show();break;}}    }        @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.main);        /*         * 初始化各個UI         */        pathText = (EditText) this.findViewById(R.id.path);        resultView = (TextView) this.findViewById(R.id.resultView);        downloadButton = (Button) this.findViewById(R.id.downloadbutton);        stopbutton = (Button) this.findViewById(R.id.stopbutton);        progressBar = (ProgressBar) this.findViewById(R.id.progressBar);        /*         * 設定點擊時間         */        ButtonClickListener listener = new ButtonClickListener();        downloadButton.setOnClickListener(listener);        stopbutton.setOnClickListener(listener);    }    private final class ButtonClickListener implements View.OnClickListener{public void onClick(View v) {switch (v.getId()) {/* * 下載按鈕 */case R.id.downloadbutton:String path = pathText.getText().toString();if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){File saveDir = Environment.getExternalStorageDirectory();//擷取儲存路徑download(path, saveDir);//開始下載}else{//記憶卡出錯Toast.makeText(getApplicationContext(), R.string.sdcarderror, 1).show();}downloadButton.setEnabled(false);//設定下載按鈕不可用stopbutton.setEnabled(true);//設定停止下載按鈕可用break;//停止下載case R.id.stopbutton:this.task.exit();//退出下載,即是去讓線程停止下載downloadButton.setEnabled(true);//下載按鈕可用stopbutton.setEnabled(false);//停止下載按鈕不可用break;}}private DownloadTask task;private void download(String path, File saveDir) {//運行在主線程task = new DownloadTask(path, saveDir);new Thread(task).start();}/* * UI控制項畫面的重繪(更新)是由主線程負責處理的,如果在子線程中更新UI控制項的值,更新後的值不會重繪到螢幕上 * 一定要在主線程裡更新UI控制項的值,這樣才能在螢幕上顯示出來,不能在子線程中更新UI控制項的值 */private final class DownloadTask implements Runnable{private String path;private File saveDir;private FileDownloader loader;public DownloadTask(String path, File saveDir) {this.path = path;this.saveDir = saveDir;}/** * 退出下載 */public void exit(){if(loader!=null) loader.exit();}public void run() {try {loader = new FileDownloader(getApplicationContext(), path, saveDir, 3);//開啟三條線程下載progressBar.setMax(loader.getFileSize());//設定進度條的最大刻度,為檔案的長度loader.download(new DownloadProgressListener() {public void onDownloadSize(int size) {Message msg = new Message();msg.what = 1;msg.getData().putInt("size", size);//把已經下載的長度傳給UI線程,在progressbar中顯示handler.sendMessage(msg);}});} catch (Exception e) {e.printStackTrace();handler.sendMessage(handler.obtainMessage(-1));}}}    }    }

源碼解析:這裡主要的是Handler的使用,他是在子線程中當下載進度發生變化之後通知UI線程去更新ProgressBar和ResultView的。而子DownloadTask線程中通過調用download方法,download中包含一個沒有下載完成之前不停止的迴圈,傳入DownloadProgressListener對象而可以監聽不斷的發現下載進度改變,之後發訊息。這樣一個輪迴就可以實現子線程不斷的發訊息給UI線程,UI線程更新群組件這樣的功能。這樣MainActivity就完美了。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.