Participe do evento ⁠#Android11: apresentação de lançamento da versão Beta no dia 3 de junho.

Evitar downloads redundantes

Muitos usuários do seu app têm acesso intermitente à Internet ou têm limites na quantidade de informações que podem ser transferidas por download para os dispositivos deles. Você pode incentivar os usuários a interagir com seu app com maior frequência reduzindo a quantidade de dados que precisam ser transferidos pelo seu app.

A maneira mais simples de reduzir seus downloads é transferir apenas o que você precisa. Em termos de dados, isso significa implementar APIs REST que permitem especificar critérios de consulta que limitam os dados retornados usando parâmetros como o horário da última atualização.

Da mesma forma, ao fazer o download de imagens, é recomendado reduzir o tamanho delas no servidor, em vez de fazer o download de imagens no tamanho original que são reduzidas no cliente.

Armazenar arquivos em cache localmente

Outra técnica importante é evitar o download de dados duplicados. Você pode reduzir a probabilidade de fazer o download dos mesmos dados repetidamente usando o cache. Ao armazenar em cache os dados e recursos do seu app, você cria uma cópia local das informações que seu app precisa referenciar. Se o app precisar acessar as mesmas informações várias vezes em um curto período, você terá que fazer o download dele no cache uma vez.

É importante armazenar em cache o mais agressivamente possível para reduzir a quantidade total de dados que você transfere por download. Sempre armazene em cache recursos estáticos, incluindo downloads on demand, como imagens em tamanho original, pelo maior tempo possível. Os recursos on demand precisam ser armazenados separadamente para permitir que você libere regularmente o cache on demand para gerenciar o tamanho dele.

Para garantir que o armazenamento em cache não resulte no app exibindo dados desatualizados, extraia dos cabeçalhos de resposta HTTP o horário em que o conteúdo solicitado foi atualizado pela última vez e quando ele expira. Isso permitirá que você determine quando o conteúdo associado precisa ser atualizado.

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;
    }
    

Usando essa abordagem, você também pode armazenar em cache o conteúdo dinâmico, garantindo que seu app não exiba informações desatualizadas.

Você pode armazenar dados não confidenciais no diretório de cache externo não gerenciado, acessado por meio de Context#getExternalCacheDir().

Como alternativa, você pode usar o cache de apps gerenciado e seguro, obtido por meio de Context#getCacheDir(). Esse cache interno pode ser liberado quando o sistema está com pouco armazenamento disponível.

Observação: arquivos armazenados no local do cache são apagados quando o app é desinstalado.

Usar o cache de resposta HttpsURLConnection

O Android 4.0 adicionou um cache de resposta a HttpsURLConnection. Você pode ativar o cache de resposta HTTP em dispositivos compatíveis usando a reflexão da seguinte maneira:

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.");
      }
    }
    

Esse código de amostra ativará o cache de resposta nos dispositivos Android 4.0 ou versões posteriores sem afetar as versões anteriores.

Com o cache instalado, as solicitações HTTP totalmente em cache podem ser atendidas diretamente do armazenamento local, eliminando a necessidade de abrir uma conexão de rede. As respostas armazenadas em cache condicionalmente podem validar o próprio nível de atualização no servidor, eliminando o custo de largura de banda associado ao download.

As respostas não armazenadas em cache são armazenadas no cache de resposta para solicitações futuras.