中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎么在Android應用中實現一個網絡多線程斷點續傳下載功能

發布時間:2020-11-30 17:48:35 來源:億速云 閱讀:138 作者:Leah 欄目:移動開發

怎么在Android應用中實現一個網絡多線程斷點續傳下載功能?很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細講解,有這方面需求的人可以來學習下,希望你能有所收獲。

原理

多線程下載的原理就是將要下載的文件分成若干份,其中每份都使用一個單獨的線程進行下載,這樣對于文件的下載速度自然就提高了許多。

既然要分成若干部分分工下載,自然要知道各個線程自己要下載的起始位置,與要下載的大小。所以我們要解決線程的分配與各個線程定位到下載的位置。

封裝

對于多線程下載我們可以將其封裝到一個工具類中DownUtil,向其中傳入下載的鏈接、文件存儲路徑、需要下載的線程數

分配線程

這里通過HttpURLConnection進行網絡請求下載,通過getContentLength()方法獲取下載文件的總大小,再對其平均分配各個線程需要下載的大小。這樣就確定了下載的大小,下面就是定位到各個線程的開始位置進行下載,這里可以使用RandomAccessFile來追蹤定位到要下載的位置,它的seek()方法可以進行定位。

線程下載

下面就是各個線程的下載DownThread,上面已經得到了各個線程要下載的初始位置,所以可以通過獲取網絡請求的輸入流InputStream,通過skip()方法跳躍到指定位置進行讀取數據,再寫入到RandomAccessFile文件中

一、 編寫基本的UI,三個TextView,分別顯示文件名、下載進度和下載速度,一個ProgressBar。二個Button,分別用于開始下載、暫停下載和取消下載。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:tools="http://schemas.android.com/tools"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:orientation="vertical"
  android:paddingBottom="@dimen/activity_vertical_margin"
  android:paddingLeft="@dimen/activity_horizontal_margin"
  android:paddingRight="@dimen/activity_horizontal_margin"
  android:paddingTop="@dimen/activity_vertical_margin"
  tools:context="com.example.linux.continuedownload.MainActivity">

  <LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
  <TextView
    android:id="@+id/textView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />

  <TextView
    android:layout_marginLeft="80dp"
    android:id="@+id/progress"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />

  <TextView
    android:layout_marginLeft="80dp"
    android:id="@+id/speed"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />
  </LinearLayout>
  <ProgressBar
    android:visibility="invisible"
    android:id="@+id/progressBar"
    
    android:layout_width="match_parent"
    android:layout_height="wrap_content" />

  <LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <Button
      android:id="@+id/start"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="開始下載" />

    <Button
      android:layout_marginLeft="20dp"
      android:id="@+id/stop"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="暫停下載" />

    <Button
      android:layout_marginLeft="20dp"
      android:id="@+id/cancel"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="取消下載" />
  </LinearLayout>

</LinearLayout>

在onCreate方法中綁定開始下載按鈕事件:點擊start按鈕,設置進度條可見,并且設置start的Action,啟動服務。

startButton.setOnClickListener(new View.OnClickListener() {
  @Override
  public void onClick(View v) {
    textView.setText(fileInfo.getFileName());
    progressBar.setVisibility(View.VISIBLE);
    // 通過Intent傳遞參數給service
    Intent intent = new Intent(MainActivity.this, DownloadService.class);
    intent.setAction(DownloadService.ACTION_START);
    intent.putExtra("fileInfo", fileInfo);
    startService(intent);
  }
});

在onCreate方法中綁定暫停下載按鈕事件:點擊stop按鈕,設置stop的Action,啟動服務。

stopButton.setOnClickListener(new View.OnClickListener() {
  @Override
  public void onClick(View v) {
    // 通過Intent傳遞參數給service
    Intent intent = new Intent(MainActivity.this, DownloadService.class);
    intent.setAction(DownloadService.ACTION_STOP);
    intent.putExtra("fileInfo", fileInfo);
    startService(intent);
  }
});

在onCreate方法中綁定取消下載按鈕事件:點擊cancel按鈕,設置cancel的Action,啟動服務,之后更新UI。

cancelButton.setOnClickListener(new View.OnClickListener() {
  @Override
  public void onClick(View v) {
    // 通過Intent傳遞參數給service
    Intent intent = new Intent(MainActivity.this, DownloadService.class);
    intent.setAction(DownloadService.ACTION_CANCEL);
    intent.putExtra("fileInfo", fileInfo);
    startService(intent);

    // 更新textView和progressBar的顯示UI
    textView.setText("");
    progressBar.setVisibility(View.INVISIBLE);
    progressView.setText("");
    speedView.setText("");
  }
});

注冊廣播,用于Service向Activity傳遞一些下載進度信息:

// 靜態注冊廣播
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(DownloadService.ACTION_UPDATE);
registerReceiver(broadcastReceiver, intentFilter);

/**
 * 更新UI
 */
BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
  @Override
  public void onReceive(Context context, Intent intent) {
    if (DownloadService.ACTION_UPDATE.equals(intent.getAction())) {
      int finished = intent.getIntExtra("finished", 0);
      int speed = intent.getIntExtra("speed", 0);

      Log.i("Main", finished + "");
      progressBar.setProgress(finished);
      progressView.setText(finished + "%");
      speedView.setText(speed + "KB/s");
    }
  }
};

三、 在AndroidManifest.xm文件中聲明權限,定義服務

<service android:name="com.huhx.services.DownloadService" android:exported="true" />

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

總結

多線程的關鍵就是分配好需要下載的進程,定位進程下載的準確位置,獲取輸入流讀取數據,同時寫入到文件的相應位置。可以借助RandomAccessFile來進行定位。

當然也并非開的線程數越多下載的速度也就越快,因為線程越多對于程序處理這些線程也是一種負擔,過多的話反而會降低下載的速度,所以要合理運用。

看完上述內容是否對您有幫助呢?如果還想對相關知識有進一步的了解或閱讀更多相關文章,請關注億速云行業資訊頻道,感謝您對億速云的支持。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

永胜县| 昌邑市| 怀远县| 永济市| 嘉祥县| 伊吾县| 长子县| 巴楚县| 巴塘县| 桦南县| 东兴市| 尚志市| 冷水江市| 大洼县| 平南县| 故城县| 韶山市| 潞西市| 青冈县| 宁安市| 绥化市| 浦东新区| 龙南县| 辰溪县| 开封市| 新邵县| 濉溪县| 南京市| 新和县| 文山县| 太康县| 淳安县| 麦盖提县| 洛南县| 万宁市| 多伦县| 铜川市| 宜章县| 贵南县| 桐乡市| 花莲市|