ContentProvider

  • ContentProvider는 앱 사이에서 각종 데이터를 공유할 수 있게 해주는 컴포넌트이다.
  • 안드로이드 표준 시스템에서는 연락처인 Contacts나 이미지나 동영상 등의 데이터를 보관하는 MediaStore등이 ContentProvider로 공개돼 있다. 
  • 데이터를 검색, 추가, 갱신, 삭제할 수 있으며, 주로 SQLite 등의 관계형 데이터베이스 이용을 염두에 두고 설계됐습니다.
  • ContentProvider가 제공하는 데이터는 ContentResolver를 통해 접근하도록 설계돼있고, ContentProvider자신에 대한 참조는 필요없다.
Cursor는 데이터에 접근하는 포인터
ContentProvider에서 데이터를 가져오는 흐름
1. ContentResolver 구하기
2. Cursor 구하기
3. Cursor에서 데이터 가져오기
4. Cursor해제

BroadcastReceiver

  • 어떤 이벤트가 발생한 사실을 앱에 알리고 싶을 때 BroadcastReceiver에 통지한다.
  • 단말기 전원이 들어왔거나 디스크 용량 부족 등 시스템의 이벤트를 앱에 알리거나, 앱간의 연계를 위해 이벤트를 알리고 싶을 때 이용한다.
  • 브로드캐스트 Intent를 받았을 때의 처리를 onReceive에서 구현한다
    어느 브로드캐스트 Intent를 받을지는 IntentFilter로 정의한다.

LocalBroadcastReceiver

브로드캐스트는 다른 앱에 송신하는 것이 가능하지만 경우에 따라서는 다른 앱에 알릴 필요없이 앱내에서 완결시키고 싶을 때 LocalBroadcast로 다른 앱에 알리지 않고 끝낼 수 있다. LocalBroadcast를 수신하려면 LocalBroadcastReceiver를 이용한다.

 

Broadcast를 수신해 처리할 때 주의할 점

안드로이드는 전력 소비를 줄이고자 사용자가 화면을 끄면 슬립 상태로 들어간다.

브로드캐스트를 수신해서 뭔가 시간이 오래 걸리는 처리를 하는 중에 슬립되는 경우가 있다.

일반적으로 화면이 꺼지고 CPU가 동작하지 않는 상태를 슬립 상태라고 한다.

이런 슬립 상태에서도 브로드캐스트를 받을 수 있지만 받은 후에 곧 바로 슬립하므로 시간이 걸리는 처리는 취소되어 계속할 수 없다.

 

처리를 계속하려면 CPU를 깨울 필요가 있다. 이런 동작을 안드로이드 시스템 세계에서는 WakeLock을 얻는다고 한다. Wake '깨운다', Lock '열쇠로 잠근다' 는 의미인데, 잠들 수 없는 방에 CPU를 넣고 열쇠로 잠가두는 것을 상상하면 쉽다. 반대로 처리가 끝나면 WakeLock을 해제한다.

 

주의할 점은 WakeLock 해제를 잊으면 CPU가 슬립할 수 없어 계속 동작하고 전력을 낭비하게 된다. 이는 앱의 신뢰성과도 연관되니 주의해야한다. 

 

다만 다행히 지원라이브러리에 WakefulBroadcastReceiver라는 클래스가 있어 이 클래스를 이용하면 처리 중에만 WakeLock을 얻고, 처리가 끝나면 해제하는 일련의 흐름을 실행해준다.
WakefulBroadcastReceiver로 얻은 WakeLock은 60초로 타임아웃이 설정돼 있다. 60초가 넘으면 슬립 상태로 전환되니 주의할 필요가 있다.


Service

  • 백그라운드 처리를 위해 준비된 컴포넌트이다.
  • UI없이 백그라운드로 처리할 수 있다.

Service의 3종류

  1. Context.startService()를 호출해 시작되는 서비스
  2. Context.bindService()를 호출해서 Service에 바인드하는 종류
  3. AIDL (Android Interface Definition Language: 안드로이드 인터페이스 정의 언어)을 이용하는 서비스
AIDL로 앱끼리 연결할 때는 각각 Service로 실행되는 스레드가 다르다는 점에 주의할 필요가 있다.
단순히 앱을 연계하고 싶을 때는 startActivityForResult()를 이용하는 액티비티 연계로 대신할 수 없는지 검토해 보는 것이 좋다.

Service의 수명주기와 콜백

onCreate Service가 생성된 뒤에 콜백된다.
onStartCommand Service가 시작된 뒤에 콜백된다.
onBind

Context.bindService()를 통해 이 Service가 바인드되는 경우에 호출된다.

또한 바인드 후, 서비스에 접속할 때는 ServiceCOnnection.onServiceConnected가 콜백된다.

onRebind

이 Service가 언바인드된 다음 다시 접속할 때 콜백된다.

onUnbind

이 Service가 언바인드될 때 콜백된다. 

onDestroy

Service가 페기되기 직전에 콜백된다.

Service가 폐기되는 타이밍

바인드된 경우는 바인드한 모든 클라이언트로부터 언바인드됐을 때 폐기된다.

 

Service가 바인드되지 않은 채 startService로 시작된 경우에는 명시적으로 Service.stopSelf()로 Service 자신이 스스로 종료하거나 다른 컴포넌트에서 Context.stopService()를 호출해 Service를 종료했을 때 폐기된다.

 

마지막으로, Service가 바인드되고 startService로 시작된 경우는 모든 클라이언트로부터 언바인드되고 또한 명시적으로 Service.stopSelf()로 Service자신이 스스로 종료하거나 다른 컴포넌트에서 Context.stopService()를 호출해 Service를 종료했을 때 폐기된다.

 

Activity와 Fragment의 수명주기에 의존하지 않고 백그라운드에서 처리하고 싶은 경우 일반적으로 IntentService가 최적의 선택이 된다.

'Android' 카테고리의 다른 글

[Android] 테스트  (0) 2020.04.11
[Android] Gradle  (0) 2020.04.10
[Android] Activity, View, Layout  (0) 2020.04.03
[안드로이드] 갤러리 앱으로 연결 시키기  (0) 2020.03.08
[안드로이드] 갤러리 구현하기  (0) 2020.02.21

+ Recent posts