避免冗余下载

使用您的应用的很多用户在访问互联网时会遇到时断时续的情况,或者他们可以下载到设备上的信息量有限。您可以通过减少您的应用需要下载的数据量来鼓励用户更频繁地与您的应用进行交互。

要减少下载内容,最基本的方法是只下载需要的内容。就数据而言,这意味着实现 REST API,此 API 允许您通过使用诸如上次更新时间之类的参数来指定限制返回数据的查询条件。

同样,在下载图片时,最好缩减服务器端图片的大小,而不是下载在客户端上缩减的完整尺寸图片。

在本地缓存文件

另一种重要方法是避免下载重复数据。您可以使用缓存降低重复下载同一段数据的可能性。通过缓存应用的数据和资源,您可以针对应用需要引用的信息创建本地副本。如果您的应用需要在短时间内多次访问同一条信息,您只需将其下载到缓存一次即可。

请务必积极地进行缓存,这样才能减少您下载的数据总量。请尽可能合理地缓存静态资源,包括按需下载内容(例如完整尺寸图片)。按需资源应分开存储,以便您能够定期清空按需缓存以管理其大小。

为确保您的缓存不会使您的应用显示陈旧数据,请务必从 HTTP 响应头文件中提取所请求内容的上次更新时间和到期时间。这样,您就可以确定何时应刷新关联内容。

Kotlin

    val conn: HttpsURLConnection = url.openConnection() as HttpsURLConnection
    val currentTime: Long = System.currentTimeMillis()
    val expires: Long = conn.getHeaderFieldDate("Expires", currentTime)
    val lastModified: Long = conn.getHeaderFieldDate("Last-Modified", currentTime)
    if (lastModified < lastUpdateTime) {
        // Skip update
    } else {
        // Parse update
        lastUpdateTime = lastModified
    }
    

Java

    // url represents the website containing the content to place into the cache.
    HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();

    long currentTime = System.currentTimeMillis();
    long expires = conn.getHeaderFieldDate("Expires", currentTime);
    long lastModified = conn.getHeaderFieldDate("Last-Modified", currentTime);

    // lastUpdateTime represents when the cache was last updated.
    if (lastModified < lastUpdateTime) {
        // Skip update
    } else {
        // Parse update
        lastUpdateTime = lastModified;
    }
    

使用此方法,您还可以有效地缓存动态内容,同时确保它不会使您的应用显示陈旧信息。

您可以将非敏感数据缓存到通过 Context#getExternalCacheDir() 获取的不受管理的外部缓存目录中。

或者,您也可以使用通过 Context#getCacheDir() 获取的受管理的安全应用缓存。请注意,当系统可用存储空间不足时,此内部缓存可能会被清空。

注意:卸载应用时,系统会清空相应缓存位置中存储的文件。

使用 HttpsURLConnection 响应缓存

Android 4.0 为 HttpsURLConnection 添加了响应缓存。您可以使用如下反射在支持的设备上启用 HTTP 响应缓存:

Kotlin

    private fun enableHttpResponseCache() {
        try {
            val httpCacheSize: Long = 10L * 1024L * 1024L // 10 MiB
            val httpCacheDir = File(cacheDir, "http")
            Class.forName("android.net.http.HttpResponseCache")
                    .getMethod("install", File::class.java, Long::class.javaPrimitiveType)
                    .invoke(null, httpCacheDir, httpCacheSize)
        } catch (httpResponseCacheNotAvailable: Exception) {
            Log.d(TAG, "HTTP response cache is unavailable.")
        }
    }
    

Java

    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 及更高版本的设备上启用响应缓存,不影响更低版本。

安装了缓存后,完全缓存的 HTTP 请求可直接通过本地存储空间提供,无需打开网络连接。有条件缓存的响应可以在服务器验证其新鲜度,从而消除了与下载相关的带宽成本。

未缓存的响应会存储在响应缓存中,以响应将来的请求。