2017-02-10 174 views
0

我有一個活動,它有兩個列表視圖。第一個listview有音樂。第二個listview顯示下載項目,每個下載項目顯示下載百分比的進度條。 如果用戶點擊音樂項目,我將下載項目添加到第二個列表視圖,並使用AsyncTask啓動下載文件。用戶可以點擊多個音樂,這意味着可以同時下載多個文件。 我可以用AsyncTask下載文件。但是因爲下載必須繼續甚至應用程序關閉,所以我想要下載服務中的文件。如何在Android中同時下載多個文件

我不知道如何與服務同時下載多個文件。我應該遵循哪些步驟?有沒有教程呢?

+1

不是答案,而是需要思考的問題。如果這是您的服務器,您可能希望避免同時過多下載大量文件。 – Lukasz

回答

7

我已經實現了同在我的生產應用之一:

  1. 創建一個表中添加要下載的項目。排序應基於項目添加下載的時間。考慮這是一個隊列。還要添加一列以檢查文件是否已經下載。如果下載,則將其從隊列中刪除。
  2. 創建一個IntentService即使應用程序關閉,它也將負責在後臺下載數據。這Service應該繼續運行,直到表隊列不是空的。只有在添加新項目或者網絡連接狀態從死亡變爲活動時才應啓動。在Service內,您應該檢查隊列是否爲空。如果空提取要添加到隊列中的表的行數(ExecutorService)以供下載。要檢查網絡狀態的比例,請使用‎LocalBroadcastManager創建BroadcastReceiver
  3. 現在您可以編寫的代碼DownloadIntentService。嘗試修改按您的需求:

    private static int NUMBER_OF_CORES = 
        Runtime.getRuntime().availableProcessors() * 2; 
    private final ExecutorService executorService; 
    private final ExecutorCompletionService<DownloadModel> executorCompletionService; 
    
    public DownloadIntentService() { 
    super("DownloadIntentService"); 
    executorService = Executors.newFixedThreadPool(NUMBER_OF_CORES); 
    executorCompletionService = new ExecutorCompletionService<>(executorService); 
    } 
    
    ...... 
    @Override 
    protected void onHandleIntent(Intent intent) { 
    
    //Check to see for storage permission 
    if (ActivityCompat.checkSelfPermission(this, 
         Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED 
         && ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) 
         == PackageManager.PERMISSION_GRANTED) { 
    ..... 
    //Now create job queue 
    .... 
    //Fetch rows to download from table 
    DownloadQuery downloadQuery = new DownloadQuery(DownloadIntentService.this); 
    
    ArrayList<DownloadModel> downloadModelArrayList = downloadQuery.getDownload(DownloadContract.IFileDownloadStatus.NOT_DOWNLOADED, 
          0, NUMBER_OF_CORES); 
    //Check if queue contains any item 
    if (downloadModelArrayList.size() > 0) { 
    if (!executorService.isShutdown()) 
            executorCompletionService.submit(new DownloadWorkerCallable(**Your download model from table to download**, DownloadIntentService.this)); 
    } 
    ..... 
    //Don't forget to shutdown the executorService 
    } 
    } 
    

DownloadWorkerCallable正在實施Runnable這實際上下載文件。

+0

@Alexander你說什麼? –

+0

謝謝。但啓動後服務用戶可以隨時添加新的下載項目。在添加的每個下載項目中,我需要開始下載新的下載項目。如果我沒有錯,在你的例子中,在啓動服務開始時獲取所有下載項目?但在我的代碼服務啓動後,用戶可以添加新的下載項目 – Alexander

+0

一旦IntentService啓動,它將繼續運行,直到task或onHandleIntent()沒有完成。我在onHandleIntent()中獲取項目。即使onHandleIntent()未完成,開始下載的新請求也將處於隊列中,並且DownloadIntentService()將不會再次啓動。還有另一種方法,你可以從onHandleIntent() –

2

您應該使用ThreadPool或更好的EventBus。 AsyncTask不適合多次下載。