일부 앱 사용자는 인터넷에 간헐적으로 액세스하거나 기기에 다운로드할 수 있는 정보의 양에 제한이 있습니다. 앱에서 다운로드해야 하는 데이터의 양을 줄여 사용자가 앱과 더 자주 상호작용하도록 유도할 수 있습니다.
다운로드를 줄이는 가장 기본적인 방법은 필요한 것만 다운로드하는 것입니다. 데이터 측면에서 이는 마지막 업데이트 시간과 같은 매개변수를 사용하여 반환된 데이터를 제한하는 쿼리 기준을 지정할 수 있는 REST API를 구현하는 것을 의미합니다.
마찬가지로 이미지를 다운로드할 때는 클라이언트에서 축소된 원본 크기 이미지를 다운로드하는 대신 서버 측에서 이미지 크기를 줄이는 것이 좋습니다.
HTTP 응답 캐시
또 다른 중요한 기술은 중복된 데이터를 다운로드하지 않는 것입니다. 캐싱을 사용하면 동일한 데이터를 반복적으로 다운로드할 가능성을 줄일 수 있습니다. 앱의 데이터와 리소스를 캐시하면 앱에서 참조해야 하는 정보의 로컬 사본이 생성됩니다. 앱이 짧은 기간 동안 동일한 정보에 여러 번 액세스해야 하는 경우 캐시에 한 번만 다운로드하면 됩니다.
다운로드하는 총 데이터 양을 줄이려면 가능한 한 적극적으로 캐시하는 것이 중요합니다. 전체 크기 이미지와 같은 주문형 다운로드를 포함한 정적 리소스는 항상 합리적으로 가능한 한 오랫동안 캐시합니다. 주문형 리소스는 주문형 캐시를 정기적으로 플러시하여 크기를 관리할 수 있도록 별도로 저장해야 합니다.
캐싱으로 인해 앱에 오래된 데이터가 표시되지 않도록 하려면 ETag 및 Last-Modified 헤더와 같은 적절한 HTTP 상태 코드 및 헤더를 사용하세요. 이렇게 하면 연결된 콘텐츠를 새로고침해야 하는 시점을 결정할 수 있습니다. 예를 들면 다음과 같습니다.
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 }
자바
// 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()
자바
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 추상화를 제공하는 저장소라는 맞춤 클래스를 만드는 작업이 포함됩니다. 저장소는 처음에는 원격 웹 서비스와 같은 다양한 소스에서 데이터를 가져올 수 있지만 후속 호출에서는 호출자에게 캐시된 버전의 데이터를 제공합니다. 이 간접 레이어를 사용하면 앱에 맞는 강력한 캐싱 전략을 제공할 수 있습니다. 앱 내에서 저장소 패턴을 사용하는 방법에 관한 자세한 내용은 앱 아키텍처 가이드를 참고하세요.