避免非优化下载

您的一些应用用户断断续续地可以访问互联网,或者对他们可以下载到设备上的信息量有限制。您可以通过减少应用需要下载的数据量来鼓励用户更频繁地与您的应用互动。

减少下载的最基本方法是只下载您需要的内容。从数据方面来说,这意味着实施 REST API,让您可以指定查询条件,通过使用诸如上次更新时间之类的参数来限制返回的数据。

同样,在下载图像时,最好在服务器端减小图像大小,而不是下载在客户端减小尺寸的全尺寸图像。

缓存 HTTP 响应

另一个重要的技巧是避免下载重复数据。您可以通过使用缓存来降低重复下载相同数据片段的可能性。通过缓存应用的数据和资源,您可以创建应用需要参考的信息的本地副本。如果您的应用需要在短时间内多次访问相同的信息片段,则只需要将其下载到缓存一次。

为了最大程度地减少下载的数据总量,尽可能积极地进行缓存非常重要。始终缓存静态资源,包括按需下载(如全尺寸图像),并且尽可能长时间地缓存。按需资源应单独存储,以便您可以定期刷新按需缓存以管理其大小。

为了确保您的缓存不会导致应用显示陈旧数据,请使用适当的 HTTP 状态代码和标头,例如 ETagLast-Modified 标头。这使您可以确定何时应刷新相关内容。例如

Kotlin

// url represents the website containing the content to place into the cache.
val conn: HttpsURLConnection = url.openConnection() as HttpsURLConnection
val currentTime: Long = System.currentTimeMillis()
val lastModified: Long = conn.getHeaderFieldDate("Last-Modified", currentTime)

// lastUpdateTime represents when the cache was last updated.
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 lastModified = conn.getHeaderFieldDate("Last-Modified", currentTime);

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

您可以配置一些网络库以自动尊重这些状态代码和标头。例如,当使用OkHttp时,为客户端配置缓存目录和缓存大小将启用库使用 HTTP 缓存,如下面的代码示例所示

Kotlin

val cacheDir = Context.getCacheDir()
val cacheSize = 10L * 1024L * 1024L // 10 MiB
val client: OkHttpClient = OkHttpClient.Builder()
    .cache(Cache(cacheDir, cacheSize))
    .build()

Java

File cacheDir = Context.getCacheDir();
long cacheSize = 10L * 1024L * 1024L; // 10 MiB
OkHttpClient client = new OkHttpClient.Builder()
    .cache(new Cache(cacheDir, cacheSize))
    .build();

配置缓存后,您可以直接从本地存储提供完全缓存的 HTTP 请求,从而无需打开网络连接。条件缓存的响应可以从服务器验证其新鲜度,从而消除与下载相关的带宽成本。未缓存的响应将存储在响应缓存中以供将来请求使用。

您可以通过使用Context.getExternalCacheDir()将非敏感数据缓存到未管理的外部缓存目录中。或者,您可以使用Context.getCacheDir()将数据缓存到受管理的安全应用程序缓存中。请注意,当系统存储空间不足时,此内部缓存可能会被刷新。

使用仓库

对于更复杂的缓存方法,请考虑使用仓库设计模式。这涉及创建一个自定义类(称为仓库),该类为某些特定数据或资源提供 API 抽象。仓库最初可能从各种来源(例如远程 Web 服务)获取其数据,但在后续调用中为调用方提供缓存的数据版本。此间接层允许您提供特定于您的应用的稳健缓存策略。有关在您的应用中使用仓库模式的更多信息,请参阅应用架构指南