권한이 없는 것도 확인이 되고, 권한 요청을 시도해야하는 Cusom UI 까지 동작을 합니다. (권한이 없기때문에)그런데 권한요청팝업을 띄우는 코드가 동작하지 않습니다. 

 

라는 질문을 받았습니다.

제 처음 답변은 

"정말 코드가 정상적으로 동작하는 코드라는 확신이 있거나, 이전에 동작하는것에 문제가 없다면"

안드로이드 버전에 따른 이슈 등을 확인하여 변경된 사항을 체크해야 한다는 것을 알려주었습니다.

 

그러나, 쉽사리 해결하지 못하고 있었기에 직접 찾아보았습니다.

 

1. 앱에서 위치데이터를 수집하기 위해 아래와 같은 퍼미션을 추가하였다.
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>

 

2. 그러나 질문자는 이전처럼 위치권한을 수락해도, 백그라운드에서 데이터를 수집할 수 없다는 것을 알고 있다.

따라서, 아래와 같은 백그라운드에서도 수집할 수 있도록 퍼미션을 추가하였다.

<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION"/>

 

3. 그 후, 권한 요청을 시도하였지만, 팝업창이 뜨질 않았다.

그로인해 질문을 하게 되었다..

 

왜 권한요청 팝업이 뜨지 않았을까?

 

공식문서에 의하면,

1. 위치권한을 요청한다.

2. 백그라운드 위치권한이 필요한 경우에는 필요한 순간에 추가적으로 요청한다.

를 권장하고 있습니다.

 

물론, 질문자도 여기까지는 이해하고 있었지만, "권장" 이라는 단어에 의하여 실 적용이 강제되지는 않는다고 생각하고 넘겼습니다.

 

하지만, 공식문서를 천천히 읽어본다면,

 

1.  API29 부터는 백그라운드 위치 권한이 있어야만 모든 상황에서 현재 위치에 대한 데이터를 얻을 수 있다.

2. 그러나, 일부 기능에서만 백그라운드 위치 정보 권한이 필요할 수 있기 때문에, 포그라운드 위치 정보를 요청하고, 이후에 필요에 따라 백그라운드 위치정보 권한을 얻는 방식을 권장한다.

3. 그러나!! API30 부터는 권장사항을 완전히 적용하였기 때문에, 포그라운드의 위치권한과 백그라운드의 위치권한을 동시에 요청한다면, 어떠한 동작도 하지 않는다고 안내하고 있다.

 

4. 따라서 권한요청 팝업을 띄울때, 두 경우를 동시에 체크하고, 동시에 요청하는 방식으로 코드를 작성한다면, API 30부터는 동작하지 않는다.

- 권장사항대로 작성하는 것이 가장 좋겠지만, API30 미만 (API29까지) 처럼 한 화면에서 모든 권한을 다 체크하고 진행하고 싶다면, 

A. 백그라운드 위치권한을 제외한 나머지 권한을 체크한다. (포그라운드 위치권한 포함)

B. 모든 권한이 허용된다면, 백그라운드 위치권한을 체크하고 요청한다.

의 순서로 진행하면 될 것 같다.

 

만약,

requestPermissions(permissionRequestArray, REQUEST_CODE ...

처럼 동시에 없는 권한을 요청하는 코드로 API30 이후의 기기까지 호환시키려는 경우라면, 4번처럼 하는 것이 의도대로 동작할 수 있을 것 같다.

Github 에서 많은 코드들, 더 좋은 코드를 작성하기 위한 고민을 하다보면 LiveData 가 등장하게 됩니다.

 

1. LiveData 란 무엇일까요?

일단, LiveData 는 Android Jetpack 의 Component 입니다.

* Android Jetpack : Jetpack은 개발자가 관심 있는 코드에 집중할 수 있도록 권장사항 준수, 상용구 코드 제거, 모든 Android 버전과 기기에서 일관되게 작동하는 코드 작성을 돕는 라이브러리 모음입니다.

 

오늘은 문서를 따라가면서 정리를 먼저 해보겠습니다. ( 영어고수가 아닌 저는 번역본과 원문을 같이 봐야합니다.. )

ps. 저처럼 영어에 약하신 분들은, 번역본만 보시지 마시고, 꼭 원문과 같이보세요! ( 자칫 잘못하면 이해를 방해합니다. )

LiveData is an observable data holder class.

LiveData는 관측 가능한 데이터 홀더 클래스입니다.

 

Unlike a regular observable, LiveData is lifecycle-aware, meaning it respects the lifecycle of other app components, such as activities, fragments, or services.

일반 관측 가능과 달리 LiveData는 수명주기 인식 기능을 갖추고 있습니다.

따라서 Activity, Fragment 또는 services와 같은 다른 앱 구성요소의 수명주기를 고려합니다.

 

This awareness ensures LiveData only updates app component observers that are in an active lifecycle state.

수명주기 인식을 통해 LiveData는 활동상태에 있는 앱 구성 요소 관찰자만 업데이트할 수 있습니다.

 

구구절절하게 써놨지만, 정리하자면...

LiveData 는 Activity,Fragment, Services 과 같은 LifeCycle 가 고려되어 동작한다.

- STARTED, RESUMED : LiveData 활동상태 , Observer 객체 업데이트 가능
- 그 외 : LiveData 비활동상태, Observer 객체 업데이트 불가능

- DESTROYED : LiveData Observer 제거 가능

 

라고 볼 수 있을 것 같습니다.


2. LiveData 를 사용했을 때 장점은 무엇일까요? 

1. UI 와 데이터 상태의 일치를 보장할 수 있습니다. ( Ensures your UI matches your data state )

LiveData 는 Observer Pattern을 따릅니다.  즉, LiveData 의 데이터가 변경될 때 마다 Observer 객체에게 알려줍니다.
Observer 객체에서는 LiveData의 데이터가 변경될 때 마다 UI 를 Update 하는 로직을 작성해둔다면
UI 와 데이터 상태의 일치를 보장할 수 있어집니다. 

 

2. 메모리 누수가 없습니다. ( No memory leaks )

메모리에 올라가있는 인스턴스를 앱이 더이상 필요하지 않음에도 GC 의 대상이 되지 못하면, 메모리누수가 발생합니다. 
LiveData 는 수명주기가 끝나면 자동으로 삭제됩니다. 즉, 메모리누수를 방지할 수 있습니다.

 

3. 중지된 액티비티로 인한 비정한 종료가 없습니다. ( No crashes due to stopped activities )

LiveData 를 관찰하고있는 Activity, Fragment, Services 등의 중지된 상태에서는 LiveData 의 변경사항에 대해 수신하지 않습니다.
따라서, LiveData 가 변경되었을 때 UI 를 수정하는 코드를 작성했다고 해도 동작하지 않으면서 비정상 종료에서 벗어날 수 있습니다.

 

4. 수동으로 수명 주기를 처리하지 않습니다.( No more manual lifecycle handling )

UI 를 구성하는 Component 들은 LiveData 를 관찰하기만 할뿐, 그 관찰을 중지하거나, 다시시작하는 행위를 하지 않습니다.
관찰하는 동안 LifeCycle 상태의 변경을 인식하기 때문에 이러한 사항들은 자동으로 관리합니다.

 

5. 항상 최신 데이터 유지합니다. ( Always up to date data )

만약 Oberver 객체가 백그라운드 상태가 되었을 때, 포그라운드 상태로 돌아오면, 그 즉시 LiveData 의 최신 데이터를 수신합니다.
따라서, 백그라운드 상태에 있을 때 데이터가 업데이트 되더라도, 포그라운드로 돌아오면 항상 최신 데이터를 유지합니다.

 

6. 구성(configuration)이 변경되었을 때, 적절하게 반응합니다. ( Proper configuration changes )

기기가 회전과 같은 구성(configuration) 의 변경으로 인한 Activity, Fragment 재생성등의 상황이 발생하면 사용가능한 LiveData 의 최신 데이터를  수신합니다.
따라서, 흔히 화면 회전시 사용해야 하는 Data 가 유실되는 경우를 쉽게 방지할 수 있어집니다.

 

7. 리소스를 공유합니다. ( Sharing resources )

LiveData 가 Observer 객체의 LifeCycle 을 인식할 수 있다는 것은, Activity, Fragment, Services 간에 객체를 공유할 수 있다는 것입니다.
LiveData 를 상속받아서 새로운 LiveData 클래스를 만들고, 싱글톤 패턴을 사용하여 구현할 수 있습니다.
<상세링크>

3. 오늘의 결론

LiveData 를 단순히 예제가 그러니까, 많은 코드들에서 쓰이고 있어서, 라는 이유로 사용하기 보다는

LiveData 의 장점들을 한번 더 기억하고, 그러한 장점을 살리는 코드를 작성해보는건 어떨까요?

'BackUp (관리중지) > Android 이론' 카테고리의 다른 글

Android Service  (0) 2021.05.14
Android Coroutine [코루틴]  (0) 2021.05.04
Fragment 와 Fragment LifeCycle 분석  (0) 2021.04.19
Activity 와 Activity LifeCycle 분석  (0) 2021.04.15
Android Context 에 대한 분석  (1) 2021.04.14

1. AndroidStudio New Project

배포 전 테스트를 위해서 새프로젝트를 생성합니다. 

 

 

2. New Module ( Type : Library )

모듈을 추가해 줍니다.

 

3.Edit Func

클래스나, 기본파일 등 만들고자 하는 기능들에 대한 코드를 작성하여 줍니다.

 

4. Project Add Lib ( Project Structure - Dependencies - app - Add Module - Check - Apply - OK)

배포하기전에 프로젝트에 모듈을 등록시켜줍니다. (잘 동작하는지는 테스트 해야하니까요! - Must 는 아닙니다.)

 

5. Test

원하는 테스트로 정상적인지 확인해줍니다.

 

6. GitHub Push

GitHub 에 프로젝트를 Push 해줍니다.

 

7. GitHub Releases ( Releases - Create a new release - Write - Publish release )

Releases 로 버전관리를 해주어야 합니다. (등록등록)

 

 

8. https://jitpack.io/

 

JitPack | Publish JVM and Android libraries

JitPack makes it easy to release your Java or Android library. Publish straight from GitHub or Bitbucket.

jitpack.io

Jitpack 에 접속하여
[GitHubUserName]/[ProjectName]  을 작성하고 Look up 을 눌러줍니다.

 

8.1 [GitHubUserName]/[ProjectName]  & Look up

Fail : 1.0.0 -> Red Log Image & Report

Success : 1.0.1 -> Green Log Image & Get it

 

 

8.2 How to

자, 이제 끝났으니 제대로 동작하는지 테스트 해보겠습니다.

 

 

9. New Project

새프로젝트를 만들어줍니다. (실제 사용될 프로젝트가 되겠지요)

 

 

10. build.gradle

build.gradle 을 수정해줍니다.

이 곳에 작성하는 내용은 Jitpack.io 에서 How to 를 통해 알 수 있었습니다.

 

11. USE

사용을 하면 됩니다~!

12. Lib Update

라이브러리를 업데이트할 때는 코드가 수정되어 Push Push Babe 를 해준 후에

Releases 에서 버전을 올려서 update 하는 식으로 진행하시면 version 에 맞게 사용이 가능합니다.! (버.전.관.리.필.수.)

+ Recent posts