編寫(xiě):kesenhoo - 原文:http://developer.android.com/training/efficient-downloads/redundant_redundant.html
減少下載的最基本方法是僅僅下載那些我們需要的。從數(shù)據(jù)的角度看,我們可以通過(guò)傳遞類(lèi)似上次更新時(shí)間這樣的參數(shù)來(lái)制定查詢數(shù)據(jù)的條件。
同樣,在下載圖片的時(shí)候,server 那邊最好能夠減少圖片的大小,而不是讓我們下載完整大小的圖片。
另一個(gè)重要的技術(shù)是避免下載重復(fù)的數(shù)據(jù)。可以使用緩存機(jī)制來(lái)處理這個(gè)問(wèn)題。緩存靜態(tài)的資源,包括按需下載例如完整的圖片(只要合理和興)。這些緩存的資源需要分開(kāi)存放,使得我們可以定期地清理這些緩存,從而控制緩存數(shù)據(jù)的大小。
為了保證 app 不會(huì)因?yàn)榫彺娑鴮?dǎo)致顯示的是舊數(shù)據(jù),請(qǐng)?jiān)诰彺嬷蝎@取數(shù)據(jù)的同時(shí)檢測(cè)其是否過(guò)期,當(dāng)數(shù)據(jù)過(guò)期的時(shí)候,會(huì)提示進(jìn)行刷新。
long currentTime = System.currentTimeMillis();
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
long expires = conn.getHeaderFieldDate("Expires", currentTime);
long lastModified = conn.getHeaderFieldDate("Last-Modified", currentTime);
setDataExpirationDate(expires);
if (lastModified < lastUpdateTime) {
// Skip update
} else {
// Parse update
}
使用這種方法,可以有效保證緩存里面一直是最新的數(shù)據(jù)。
我們可以緩存非敏感數(shù)據(jù)到非受管的外部緩存目錄(目錄會(huì)是sdcard下面的Android/data/data/com.xxx.xxx/cache
):
Context.getExternalCacheDir();
或者,我們可以使用受管/安全的應(yīng)用緩存。請(qǐng)注意,當(dāng)系統(tǒng)的可用存儲(chǔ)空間較小時(shí),存放在內(nèi)存中的數(shù)據(jù)有可能會(huì)被清除(類(lèi)似:system/data/data/com.xxx.xxx./cache
)。
Context.getCache();
緩存在上面兩個(gè)地方的文件都會(huì)在 app 卸載的時(shí)候被清除。
Ps:請(qǐng)注意這點(diǎn):發(fā)現(xiàn)很多應(yīng)用總是隨便在 sdcard 下面創(chuàng)建一個(gè)目錄用來(lái)存放緩存,可是這些緩存又不會(huì)隨著程序的卸載而被刪除,這其實(shí)是不符合規(guī)范,程序都被卸載了,為何還要留那么多垃圾文件,而且這些文件有可能會(huì)泄漏一些隱私信息。除非你的程序是音樂(lè)下載,拍照程序等等,這些確定程序生成的文件是會(huì)被用戶需要留下的,不然都應(yīng)該使用上面的那種方式來(lái)獲取 Cache 目錄。
在 Android 4.0
里面為 HttpURLConnection
增加了一個(gè)響應(yīng)緩存(這是一個(gè)很好的減少 http 請(qǐng)求次數(shù)的機(jī)制,Android 官方推薦使用 HttpURLConnection 而不是 Apache 的 DefaultHttpClient,就是因?yàn)榍罢卟粌H僅有針對(duì) android 做 http 請(qǐng)求的優(yōu)化,還在4.0上增加了 Reponse Cache,這進(jìn)一步提高了效率)。我們可以使用反射機(jī)制開(kāi)啟 HTTP response cache,看下面的例子:
private void enableHttpResponseCache() {
try {
long httpCacheSize = 10 * 1024 * 1024; // 10 MiB
File httpCacheDir = new File(getCacheDir(), "http");
Class.forName("android.net.http.HttpResponseCache")
.getMethod("install", File.class, long.class)
.invoke(null, httpCacheDir, httpCacheSize);
} catch (Exception httpResponseCacheNotAvailable) {
Log.d(TAG, "HTTP response cache is unavailable.");
}
}
上面的示例代碼在 Android 4.0 以上的設(shè)備上會(huì)開(kāi)啟 response cache,同時(shí)不會(huì)影響到之前的程序。
在cache被開(kāi)啟之后,所有cache中的HTTP請(qǐng)求都可以直接在本地存儲(chǔ)中進(jìn)行響應(yīng),并不需要開(kāi)啟一個(gè)新的網(wǎng)絡(luò)連接。被cache起來(lái)的response可以被server所確保沒(méi)有過(guò)期,這樣就減少了下載所需的帶寬。
沒(méi)有被cached的response會(huì)為了方便下次請(qǐng)求而被存儲(chǔ)在response cache中。