android離線下載的相關知識,android離線
離線下載的功能點如下:
1.下載管理(開始、取消下載)。
2.網路判斷(Wi-Fi,3G)。
3.獨立進程。
4.定時和手機催醒。
5.自啟動。
選擇離線下載的核心方法 後台獨立運行,我們很容易想到服務(Service),但是有以下幾種問題(1)如果服務的進程和應用一致,那麼在應用退出後,服務會重啟一次(2)如果服務的進程和應用不一致,進程間的通訊就會麻煩一點(3)如果服務的進程和應用一致,選擇IntentService,可以避免重啟問題而且我們不需要多個任務同時下載,用IntentService完全可以,而且IntentService還有其他優勢
1.下載管理
這裡不便關注下載的細節方法,網路下載的方法很多,大概如下:
1 /** 2 * 下載檔案 3 * @param url 4 * @param dest 下載存放的本地檔案 5 * @param append 斷點續傳 6 * @return 7 * @throws Exception 8 */ 9 public long download(String url, File dest, boolean append) throws Exception{10 //初始設定變數11 //準備工作12 // ... ...13 14 try {15 // ... ...16 while((readSize = is.read(buffer)) > 0){17 //網路判斷18 19 os.write(buffer, 0, readSize);20 os.flush();21 22 //如果需要停止下載,如取消,跳出當前下載23 }24 }25 } finally {26 // ... ...27 }28 // ... ...29 }
這裡要注意幾點:
(1).在下載的時候,我們希望能及時檢測到網路狀況,比如由Wi-Fi切換到3G網路下,我們應該能及時停止下載。
(2).當使用者選擇取消下載的時候,我們也能停止當前下載。
2.網路判斷
擷取當前網路狀態,主要分為Wi-Fi和Mobile(包括3G,GPRS)兩種,我們寫一個工具類如下:
1 public class NetworkUtils { 2 3 public final static int NONE = 0;//無網路 4 public final static int WIFI = 1;//Wi-Fi 5 public final static int MOBILE = 2;//3G,GPRS 6 7 /** 8 * 擷取當前網路狀態 9 * @param context10 * @return11 */12 public static int getNetworkState(Context context){13 ConnectivityManager connManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);14 15 //行動電話通訊判斷16 State state = connManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE).getState();17 if(state == State.CONNECTED||state == State.CONNECTING){18 return MOBILE;19 }20 21 //Wifi網路判斷22 state = connManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI).getState();23 if(state == State.CONNECTED||state == State.CONNECTING){24 return WIFI;25 }26 return NONE;27 }28 }
根據網路狀態,我們能夠控制下載方式:
(1).下載量很大的情況下,我們不大可能在3G情況下進行下載,容易引起使用者的反感和擔憂。
(2).當客戶十分確認可以在3G情況下進行下載,那麼也是允許的。
所以,這裡提出一個需求,我們要為下載方式設定一個靈活的等級,結合離線下載的特點,我們給出3中方案由使用者選擇:
(1).移動資料情況下自動下載
(2).只允許Wi-Fi情況下自動下載
(3).關閉下載
這裡只列出了自動下載,是因為如果不是自動下載,手動下載使用者可以隨意控制,無需設定,當然設計到丟流量情況下,如3G下手動下載,提示使用者會消耗較大的資料流量,慎用即可。
1 public class Constant { 2 //離線下載網路設定 3 public final static int OFFLINE_MOBILE = 0; 4 public final static int OFFLINE_WIFI = 1; 5 public final static int OFFLINE_OFF = 3; 6 } 7 8 public class Global { 9 //設定預設關閉狀態,10 //為了應用程式下次啟動能夠記住使用者選擇,在第一次啟動應用的時候,這個值最終應該存放到資料庫中,11 public static int OfflineNetworkSetting = Constant.OFFLINE_OFF;12 }
現在可以根據規則比較當前網路和離線網路設定,判定離線下載服務的開啟。
3.獨立進程
離線下載,無論何時何地,只要適宜進行,則當進行,目前主流的做法是建立後台服務。
1 public class OfflineSerivice extends Service {2 // ... ...3 }
(1).OfflineService的進程如果預設和應用程式一致,則在應用進程kill的時候,會重啟一次(網易新聞在離線下載的時候,退出應用,下載會停頓一小會兒就是這個原因),如果影響不大,這個方案也是可選的。
(2).OfflineService的進程和應用程式分開,如應用程式進程為"cn.cnblogs.tianxia.download",則離線下載服務的進程設定為"cn.cnblogs.tianxia.download.offline",撇清和應用程式的進程的關係。當然,這個會帶來一個新的問題,處理序間通訊,當然因為離線下載和應用程式間的模組比較獨立,這個問題還算比較好規避。
(3).OfflineService的進程如果預設和應用程式一致,但是OfflineService繼承IntentService,可避免重啟的問題,這個是《Pro Android 3》書中提到的方法,非常的好用,但是非常遺憾,本人最近才看到,暫時沒有親手測驗,不敢在工作中試用。
按理說,方案3是最佳方案, 但是個人原因,選擇了方案2.
1 <manifest xmlns:android="http://schemas.android.com/apk/res/android"2 package="com.cnblogs.download">3 <application android:icon="@drawable/icon" android:label="@string/app_name"> 4 5 <service android:name="cn.cnblogs.download.OfflineService" android:process="cn.cnblogs.download.offline"/>6 </application>7 </manifest>
4.定時下載和手機催醒
根據使用者佈建,在wifi的情況下自動下載,但是自動下載的方案有很多種,頻繁的更新下載,定點下載(早上8點,下午4點),間隔下載(每隔6小時)。
這裡,我們選擇每隔6個小時下載。
(1).這裡介紹一種錯誤的方案。一看到每隔6小時,很容易想到開啟一個子線程計時,累計到6個小時,子線程通知下載服務開始新一輪下載。這個方案的思路是沒有錯的,但是卻忽略了手機處於休眠狀態,這個子線程其實是停止執行的,那麼所謂的6個小時的效果就又可能永遠達不到,而且必然不正確或者不準確。
(2).所以,需要使用到一種不休眠的辦法:定時器和廣播接收器。每隔6小時我們發送一個廣播,廣播接收器通知開始離線下載。(可參考newsrob源碼和書籍《Pro Android 3》):
1 public class OfflineSerivice extends Service { 2 3 //上次成功下載的時間 4 private long lastDownloadTime; 5 // 省略代碼... ... 6 7 public static void startAlarm(Context context){ 8 AlarmManager alarmManager = (AlarmManager) context.getSystemService("alarm"); 9 10 //每隔6個小時發送廣播到OfflineAlarmReceiver11 //也可以設定為10分鐘檢測一下下載條件,而在OfflineAlarmRecrive中判斷開始下載,避免6小時下載失敗需再等待6小時過長時間的問題12 Intent intent = new Intent(context,OfflineAlarmReceiver.class); 13 14 PendingIntent pendingIntent = PendingIntent.getBroadcast(context.getApplicationContext(), 0, intent, 0);15 alarmManager.cancel(pendingIntent);16 alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,System.currentTimeMillis(), 3600000*6, pendingIntent);17 }18 }
OfflineAlarmRecriver中處理開始下載條件,並通知開始下載
1 public class OfflineAlarmReceiver extends BroadcastReceiver { 2 @Override 3 public void onReceive(Context context, Intent arg1) { 4 5 // 省略代碼...,初始設定變數,準備工作... 6 7 if(System.currentTimeMillis()-OfflineService.lastDownloadTime>3600000*60&&其他條件){ 8 //開啟離線下載服務 9 Intent alarmIntent = new Intent(context, OfflineService.class);10 context.startService(alarmIntent);11 }12 }13 14 }
前面我們提到了線程休眠的問題,需要在下載的時候能夠喚醒手機,下載完成後能回到休眠狀態,下面是兩個工具方法:
1 public static PowerManager.WakeLock wakeLock; 2 /** 3 * 喚醒服務 4 */ 5 public static void acquireWakeLock(Context context){ 6 7 if(wakeLock!=null){ 8 return; 9 }10 PowerManager powerManager = (PowerManager)(context.getSystemService(Context.POWER_SERVICE));11 wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "com.cnblogs.download.OfflineService");12 wakeLock.acquire();13 }14 15 /**16 * 釋放喚醒服務,返回休眠狀態17 */18 public static void releaseWakeLock(){19 if(wakeLock!=null&&wakeLock.isHeld()){20 wakeLock.release();21 wakeLock = null;22 }23 }
其中PowerManager.PARTIAL_WAKE_LOCK意思是僅喚醒CPU方式,此時能自動主動式偵測網路狀態,從而保證網路正常。
需要在Mainifest.xml中設定許可權:
<uses-permission android:name="android.permission.WAKE_LOCK" />
然後在下載服務的onStartConmmand()啟用催醒狀態,然後在下載完成後釋放催醒狀態:
1 @Override2 public int onStartCommand(Intent intent, int flags, int startId) {3 acquireWakeLock(OfflineService.this);4 //省略代碼... ...5 return super.onStartCommand(intent, flags, startId);6 }
5.自啟動
為了代碼清晰,我們再定義一個自啟動的receiver:
1 /** 2 * 自啟動離線下載服務 3 * @author user 4 */ 5 public class OfflineReceiver extends BroadcastReceiver { 6 @Override 7 public void onReceive(Context context, Intent arg1) { 8 //啟動定時器 9 OfflineService.startAlarm(context);10 }11 }12 在AndroidManifest.xml註冊此接收器,如下:13 14 <receiver android:name="cn.cnblogs.download.OfflineReceiver">15 <intent-filter>16 <!--自啟動-->17 <action android:name="android.intent.action.BOOT_COMPLETED" /> 18 <category android:name="android.intent.category.HOME" /> 19 </intent-filter>20 </receiver>
這樣,在啟動的時候,能夠接受啟動廣播,並執行啟動定時器操作。
6.小結
為了簡潔明晰,開門見山,本文僅針對離線下載的最重要的關聯點列舉說明,而對於清理策略,手動和自動模式,介面跳轉,UI設計和業務要求沒有過多的涉及,但是往往這些東西才是花費你大量的時間,需要大量細節的積累和耐心的調試,我們唯一要做的事情就是不斷的完善!
安卓離線版遊戲下載網址
網址的話機鋒市場,安卓市場什麼的有很多資源,其實只要串連360手機小幫手或者豌豆莢,及91助手這三個中的一個都有很多遊戲以及軟體資源。也很方便
安卓手機離線地圖怎下載
很簡單,你直接開啟百度(或搜狗、或搜搜、或高德等等)手機地圖首頁,在下載自己手機適用的安卓地圖軟體的同時,查看離線地圖的介紹或者使用協助即可,一般直接將下載下來的地圖資料拷貝到sd卡或sd卡中對應檔案夾即可,再開啟手機地圖軟體他提示離線匯入成功就能用了