84669 人學習
152542 人學習
20005 人學習
5487 人學習
7821 人學習
359900 人學習
3350 人學習
180660 人學習
48569 人學習
18603 人學習
40936 人學習
1549 人學習
1183 人學習
32909 人學習
想实现一个后台下载的功能,类似百度地图离线包下载,当下载任务在进行时可以返回其他界面进行其他的操作,下载列表所在的界面为activity1,其他界面为activity2,当在activity1中点击几个任务进行下载时,返回了activity2进行其他操作,过一段时间后再进入activity1怎么显示当前的下载进度?
ringa_lee
下載任務顯然需要在主執行緒之外處理。 而從目前執行下載任務的activity按了返回鍵,然後再次進入後,該activity已經被銷毀並且重建了,並且一般情況下,在activity被銷毀後,我們應該清理新建的線程,以避免無法預料的後果。所以activity重建後顯示目前下載資訊的各種UI元件也就無法顯示正確的狀態了。 而Service與UI無關,可以在後台長時間運作;Bound service 更是允許 app 元件和 service 溝通:發送要求(例如下載要求)、取得狀態(例如下載進度)。
所以,一個可行的解決方法是:
AsyncTask 負責另起一個線程下載,並且定義一個接口,實現該接口就可以獲得下載進度及其它下載信息。
Bound Service 負責在後台啟動 AsyncTask,並且管理該下載任務;實現 AsyncTask 定義的接口,把獲取的下載信息以廣播的形式發送出去;
Activity 在綁定到 service 後,就可以透過 service 啟動一個下載任務;然後實作一個 broadcast receiver,接收下載資訊並更新UI.
如果對service不了解,可以點這裡連結1;對綁定也不了解,可以點這裡連結2。
public class DownloadTask extends AsyncTask<Void, Integer, Long> { // 维护下载大小、下载进度、下载速率等信息。 private long downloadPercent; // 构造器,指定下载的url和存储路径。 public DownloadTask(Context context, String url, String path); @Override protected Long doInBackground(Void... params) { // 根据获取的url,执行下载任务。 } @Override protected void onProgressUpdate(Integer... progress) { // 定义一个callback,实现该callback的即可获得进度的更新。 if (listener != null) listener.updateProcess(this); }
public class DownloadService extends Service { // Activity绑定该service后,就可以调用这个方法启动一个下载任务。 public void startDownloadTask(String url) { DownloadTask task = newDownloadTask(url); task.execute(); } private DownloadTask newDownloadTask(String url) throws MalformedURLException { // 实现该接口就可以获得下载进度及其它下载信息,然后以广播的形式把获取的信息发送出去。 DownloadTaskListener taskListener = new DownloadTaskListener() { @Override public void updateProcess(DownloadTask task) { Intent updateIntent = new Intent(ACTION_DOWNLOADING_STATUS); updateIntent.putExtra(MyIntents.PROCESS_PROGRESS, task.getDownloadPercent()); sendBroadcast(updateIntent); } }; return new DownloadTask(this, url, /path/to/store/, taskListener); } }
public class DownloadActivity extends FragmentActivity { // 在onStart中绑定service,注册receiver protected void onStart(); // 在onStop中取消绑定,取消注册receiver protected void onStop(); // 实现一个ServiceConnection,在onServiceConnected()回调方法中获取service private ServiceConnection mConnection = new ServiceConnection() {} // 实现一个BroadcastReceiver,在onReceive()回调方法中获取intent,从中解析下载信息然后更新UI. private BroadcastReceiver mDownloadingStatusReceiver = new BroadcastReceiver() {} // 获取service后,就可以启动一个下载任务了。 mService.startDownloadTask(URL); }
完整的程式碼可以從這裡取得 https://github.com/li2/DownloadDemo這只是一個demo,用於演示bound service和async task是如何實現後台下載任務的。 該Demo從這個專案裡yingyixu/android-download-manager (1) 借用了核心程式碼;(2) 使用Binder class實作service,取代原工程中使用的AIDL方式(因為該方式實作複雜,而Binder已經可以滿足你的需求,而且很容易理解);(3) 刪除了管理多個下載任務的程式碼。
建議了解實作方法後,直接使用第三方框架。
據我所知下載進度斷點續傳什麼的是要存在資料庫裡的,所以把下載進度存在資料庫裡,下次進入的時候顯示這個下載進度,就好了
既然是後台下載,當這個介面再次顯示的時候,取得正在後台下載的任務,顯示到目前介面不就行了嗎
可以寫一個Service進行後台下載工作,Activity1和該Service綁定,透過Intent及Binder來實現Service和Activity1進行資料交換(即你說的從Activity2回到Activity1時下載進度變化處理),具體實現你需要對Service,Service跟Activity互動有更深的理解了,可以照這個思路去找資料學習和實現,祝你成功。
在service中進行下載,Activity1使用bindservice()方法與service綁定,並在service中設定回調方法。下載的時候呼叫這個回呼方法把進度傳給Activity1
下載任務顯然需要在主執行緒之外處理。
而從目前執行下載任務的activity按了返回鍵,然後再次進入後,該activity已經被銷毀並且重建了,並且一般情況下,在activity被銷毀後,我們應該清理新建的線程,以避免無法預料的後果。所以activity重建後顯示目前下載資訊的各種UI元件也就無法顯示正確的狀態了。
而Service與UI無關,可以在後台長時間運作;Bound service 更是允許 app 元件和 service 溝通:發送要求(例如下載要求)、取得狀態(例如下載進度)。
所以,一個可行的解決方法是:
AsyncTask 負責另起一個線程下載,並且定義一個接口,實現該接口就可以獲得下載進度及其它下載信息。
Bound Service 負責在後台啟動 AsyncTask,並且管理該下載任務;實現 AsyncTask 定義的接口,把獲取的下載信息以廣播的形式發送出去;
Activity 在綁定到 service 後,就可以透過 service 啟動一個下載任務;然後實作一個 broadcast receiver,接收下載資訊並更新UI.
如果對service不了解,可以點這裡連結1;對綁定也不了解,可以點這裡連結2。
AsyncTask負責另一個執行緒下載
Bound Service負責在背景啟動AsyncTask,並管理下載任務
Activity負責綁定service,實作一個 broadcast receiver,接收下載資訊並更新UI
完整的程式碼可以從這裡取得 https://github.com/li2/DownloadDemo
這只是一個demo,用於演示bound service和async task是如何實現後台下載任務的。
該Demo從這個專案裡yingyixu/android-download-manager (1) 借用了核心程式碼;(2) 使用Binder class實作service,取代原工程中使用的AIDL方式(因為該方式實作複雜,而Binder已經可以滿足你的需求,而且很容易理解);(3) 刪除了管理多個下載任務的程式碼。
建議了解實作方法後,直接使用第三方框架。
據我所知下載進度斷點續傳什麼的是要存在資料庫裡的,所以把下載進度存在資料庫裡,下次進入的時候顯示這個下載進度,就好了
既然是後台下載,當這個介面再次顯示的時候,取得正在後台下載的任務,顯示到目前介面不就行了嗎
可以寫一個Service進行後台下載工作,Activity1和該Service綁定,透過Intent及Binder來實現Service和Activity1進行資料交換(即你說的從Activity2回到Activity1時下載進度變化處理),具體實現你需要對Service,Service跟Activity互動有更深的理解了,可以照這個思路去找資料學習和實現,祝你成功。
在service中進行下載,Activity1使用bindservice()方法與service綁定,並在service中設定回調方法。下載的時候呼叫這個回呼方法把進度傳給Activity1