본문 바로가기
Android 개발/Room, Realm, Databases

Room을 이용해서 Offline Cache 구현하는 방법 정리 #Android

by Developer88 2020. 5. 14.
반응형

오늘은 구글의 Room Persistence Library를 이용하여,

Offline Cache를 구현하는 방법에 대해서 정리해 보도록 하겠습니다.

 

참고로 Room Library의 기본적인 구현에 대한 것은 아래 글을 참조해 주세요.

>> Room Persistence Library에 대해서 정리해 봅니다 #Android #SQLite

 

1. Offline Cache

만약 Instagram이나 Facebook의 이용자들이,

와이파이나 LTE 등이 동작하지 않는 엘리베이터 같은 곳에 가게 되었다고 가정하겠습니다.

이런 상황에서 앱을 키면 사용자들은 어떻게 되기를 원할까요?

사용자들은 예전에 보고 있던 피드들이 나오기를 원하는데요.

 

이러한 구조를 만들기 위해서는,

네트워크를 통해 받은 데이터들을 로컬에서 저장해 가지고 있는,

Offline Cache를 구현해 주어야 합니다.

 

2. Caching하는 방법

offline caching을 하는 방법들에 대해서 간단히 보고 가도록 하겠습니다.

크게 세가지 정도를 생각해 볼 수 있는데요.

 

첫번째가 바로 Room Library같은 Database Library를 이용해서,

DB에 원하는 구조의 객체 형태로 데이터를 저장해서,

Cache 로서 사용하는 것 입니다. 이 글에서 정리해 보려고 하는 방법이지요.

 

두번째는, Retrofit같은 HTTP client Library를 사용해서 Caching을 하는 것 입니다.

다만 원하는 data 클래스의 형태로 네트워크데이터를 caching하는데도 한계가 있고,

동시에 여러곳에 네트워크 Request를 한 결과값에 대해서 Caching하기에도 조금 복잡한 부분이 있습니다.

 

마지막으로는, File형태로 app내에서만 사용할 수 있는 Private한 형태로 저장하는 것 인데요.

Image파일이나 Data파일등을 사용할 수 있을 텐데요.

이러한 파일들을 효율적으로 관리해 주어야 된다는 점이 부담이 될 수 있겠네요.

 

3. Caching 할 때 주의할 점 들

3-1. Database에 저장하기 전, 서버의 응답이 정상인지 확인

유효하지 않은 혹은 정상적이지 않은 값을 Caching하지 않도록,

해당 Result가 정상적인지 확인하고, Caching을 해 주어야 합니다.

 

3-2. Database의 Model과 Domain의 Model의 구분

네트워크를 통해서 받은 데이터를

Database의 데이터 객체와

Domain영역인 UI에서 사용하는 데이터 객체로 구분해 주는 것이 좋은데요.

 

아래와 같이 Kotlin의 Extension Function을 사용해주면 편리합니다.

특히 Database객체로 사용하는 경우에는, Array타입으로 return 해 주어서,

insert할 때에 가변인자의 지시어인 vararg의 인자로 넣기 편하게 해주면 더욱 좋지요.

 

 

 

이제 준비가 되었으니, Room Library를 이용해서 Offline Cache를 구현해 보도록 하겠습니다.

 

5. Offline Cache의 구현

5-1. Entity, Dao, Database 구현

이제 단순한 형태의 offline cache를 코드로 직접 구현해 보도록 하겠습니다.

먼저 아래와 같이 Room에서의 테이블인 Entity를 정의해 줍니다.

 

Dao클래스도 아래와 같이 정의해 줍니다.

insertAll메소드와 select all을 위한 메소드 두가지 입니다.

 

 

getAll()메소드의 return타입이 LiveData타입이라면,

이것을 Observe하는 UI에 바로 반영되게 할 수 있는데요.

따라서 아래와 같이 변경해 줍니다.

 

Room과 LiveData의 궁합은 매우 강력한데요.

LiveData타입으로 return시에는 Room이 알아서 Background에서 Query를 해 줍니다.

UI에서 LiveData타입의 데이터를 Observe해서 최신화 시켜줄 수 있는 것도 장점이구요.

 

 

테이블인 Entity도 정의되었고, Dao인터페이스도 정의되었으니,

남은 건 Database 입니다.

아래와 같이 Singleton으로 생성할 수 있도록 해 줍니다.

 

 

 

ThreadSafe하게 database객체를 사용하기 위해서,

synchronized로 감싸줍니다.

 

 

이제 앱에서 사용할 Database객체도 준비가 되었으니, 사용만 해 주면 되겠습니다.

아래에서 ViewModel을 구현해 보도록 하겠습니다.

 

5-2. ViewModel 구현

정석적인 MVVM모델 에서는 Repository클래스를 분리해서 구현하겠지만,

여기서는 ViewModel에서 간단히 구현해도록 하겠습니다.

 

init블록에서 ViewModel이 최초에 실행될 때,

네트워크에서 리프레쉬 될 수 있도록 최초에 한번 Netowork에서 데이터를 가져와서,

insertAll함수에 인자로 넣어서 Room DB를 업데이트 해 줍니다.

(참고로 mDummyStudentFromNetworks는 네트워크에서 가져왔다고 가정하에 사용한 더미 데이터의 변수일 뿐입니다.)

 

 

 

studentDao의 getAll함수는 결과값을 LiveData타입으로 돌려주므로,

아래와 같이, students변수에 담아서 ViewModel의 변수로 사용해 주면 되겠습니다.

 

다만, getAll에서 돌려주는 database에서 사용하는 객체를

domain영역에서 사용하는 객체로 분리하기 위해서 asDomainModel 확장함수를 사용해 주었습니다.

 

 

 

5-3. View컨트롤러에서 Observe

이제 아래와 같이, Activity나 Fragment에서 해당 livedata를 observe해주기만 하면 되겠습니다.

 

 

이상으로 Room을 이용해서 Offline Cache를 구현하는 방법에 대해서 정리해 보았구요.

더 좋은 방법이 있다면 이 글을 통해서 업데이트 하도록 하겠습니다.

 

728x90

댓글