Data caching
네트워크 성능을 향상하기 위해서는 데이터 캐싱이 중요합니다.
기본적으로 네트워크를 통해 데이터를 다운로드하여 읽는 것보다 내부 저장소에서 바로 읽는 것이 빠릅니다.
따라서 만약 이 데이터가 여러 번 쓰일 거라면, 네트워크를 통해 데이터를 다운로드하여 내부 저장소에 저장(캐싱)하는 것이 훨씬 효율적입니다.
하지만 안드로이드에서는 기본적으로 HTTP response 캐싱을 하고 있지 않습니다.
HTTP response 캐싱을 할 수 있는 몇 가지 방법에 대해 정리했습니다.
HTTPResponseCache 클래스를 이용하여, 지정한 저장 공간에 지정한 크기만큼 캐시 할 수 있습니다.
일단 이용하면 앱의 모든 HTTP response가 파일 시스템에 캐시 됩니다.
URL 접속이나 HTTP URL 접속 등 API 뿐만 아니라 어느 HTTP 요청에도 똑같이 적용됩니다.
// Using URL
BitmapFactory.decodeStream((InputStream)new URL(pathToImage). getContent());
// Using HTTP
HttpClient client = new DefaultHttpClient();
HttpGet request = new HttpGet(url);
HttpResponse response = client.execute(request);
HTTP response cache를 이용하여, 캐시 유무와 기간을 설정할 수 있습니다.
아래와 같이 두 가지 방법으로 캐시 된 데이터가 삭제될 수 있습니다.
1. 캐시가 가득 찬 경우, 시스템은 새 파일의 공간을 확보하기 위해 가장 오래된 파일부터 삭제.
2. 파일은 각 캐시 컨트롤 헤더의 서버 response을 포함한 정보에 의해 파일을 삭제.
https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9
HTTP 1.1 표준의 경우 서버는 요청된 데이터와 함께 플래그를 전달하여 정보가 캐시 되어야 하는 시간을 알려줍니다.
만약 3일 동안 캐시 하라고 한다면 파일을 3일 동안 보존했다가 지우고, 캐시를 하지 말라고 했다면 아예 캐시 하지 않을 겁니다.
기본적으로 HTTP response cache는 캐시 콘텐츠에 대한 모든 제어를 서버에게 맡기기 때문에 요청하는 데이터의 종류와 이용 방법을 잘 알고 있고, 간단한 네트워크 상황이나 서버를 각 데이터 유형별로 정확히 캐싱 설정해서 제어할 수 있을 때는 좋은 방법입니다.
하지만 그렇지 않을 경우, 특히 서버를 제어하지 않으면, 정말 큰 문제가 발생할 수 도 있습니다.
1. 서버가 캐싱 기간을 설정하지 않아 아무것도 캐시 되지 않을 수 있습니다.
2. 네트워크 환경을 잘못 인지하여 실제 네트워크 환경에 맞게 반응하지 못할 수 있습니다.
3. 캐시 할 여유 공간을 잘못 예측하여 다른 저장공간과 충돌할 수 있습니다.
Http response cache 대신 직접 캐싱 솔루션을 만들 수 있습니다.
1. Write your own Disk Cache manager
직접 디스크 캐시 매니저를 작성하여 필요에 따라 리소스를 캐시 하고 가져오기.
2. Use custom Caching Logic
데이터 유형과 기기 자체의 상태에 기반한 커스텀한 캐싱 로직 이용.
하지만 디스크 캐시를 직접 작성하기는 쉽지 않습니다.
만약 커스텀하게 수정을 원치 않는다면 안드로이드에서 제공하는 DistLRUCache.java를 그대로 이용하는 것도 좋은 방법입니다.
서버에서 가져오는 데이터의 유형에 따라, 캐싱 정책을 정의하기가 복잡한 경우가 많습니다.
다행히도 이를 쉽게 구현할 수 있는 라이브러리들이 있습니다.
신입 때 캐싱 직접 만들다가 ANR, OOM만 잔뜩 걸렸던 기억이 나네요.
오픈 소스, 라이브러리 가져다 씁시다.