Regular Motion

개발자가 상팔자

Tag: android (page 1 of 10)

[Android] SecurityException when Notification is being registered with Vibration

안드로이드 개발을 하다보면 재현이 되지 않는 버그들이 참 많다.  어떤 버그들은 특정 기기에서만 발생하고, 또 어떤 버그는 특정 OS 버전에서만 발생하기도 한다.  따라서 상용 서비스는 반드시 CrashliticsSplunk Mint와 같은 버그 리포트 서비스를 연동 후 배포하기를 권장한다.

실 사용자가 10만명 정도되는 앱에 버그 리포트 서비스를 연동해보면 별 회개망칙한 버그들을 다 볼 수 있다.

오늘 수정한 버그는 앱에서 Notification을 등록 할 때 발생하는 Vibrate로 인해 SecurityException이 발생 할 수 있는 버그다.

앱에서 Notification을 등록 할 때, setVibrate() 함수 또는 setDefaults() 함수로 진동을 줄 수 있는데 이때 사용자 기기의 OS 버전이 4.2.1 미만이고 AndroidManifest.xml에  Vibrate 권한을 설정하지 않았다면 SecurityException이 발생 할 수 있다. (‘발생한다’가 아니라 ‘발생 할 수 있다’고 표현하는 이유는 테스트 결과 일부 기기는 4.2 미만에서도 SecurityException이 발생하지 않는다.)

Android 4.2.1에 이 문제와 관련해서 패치가 있었다. 읽어보면 기기가 진동모드여서 진동이 불가피한 경우거나 setDefaults()의 인자로 Vibrate를 설정하는 경우는 더 이상 AndroidManifest.xml에 Vibrate 권한을 추가 할 필요가 없다. 다만 setVibrate() 함수를 통해 Custom Vibration pattern을 등록하는 경우는 여전히 권한 추가가 필요하다.

따라서 우리는 AndroidManifest.xml에 아래와 같이 권한을 추가하여 꼭 필요한 기기에 한해서만 권한을 요청하도록 설정 할 수 있다.

 

아마 내부 테스트 중에는 Vibrate와 관련한 권한 문제가 없었는데, 버그 리포트로 처음 접한다면 위에서 언급한 문제일 확률이 매우 높다.

 

[Android] Doubt till your Bug Tracking tool.

AndroidStudio의 Monitors로 memory monitoring 중 기이한 현상을 발견했다.

앱에서 다운로드를 시작하면 장판처럼 고요하던 메모리가 요동을 치기 시작하는 것이다.

실제로 3~5MB 정도의 메모리가 매우 빠른 속도로 할당/해제를 반복한다. 저사양 단말에서 파일 다운로드시 앱이 굉장히 느려지는 현상도 왠지 요동치는 그래프와 깊은 관련이 있을 것 같다.

다운로드 중 Monitors 툴에 나타나는 그래프는 아래와 같다.

요동치는 메모리

17초부터 다운로드가 시작됐고, 이후 요동치는 메모리를 보시라. 길에서 탕웨이를 우연히 만나면 내 심장도 저렇게 요동 치겠지.

처음에는 다운로드 중 Notification과 View를  갱신하기 때문에 메모리가 요동치는 줄 알았는데, 해당 작업을 주석처리 후 테스트 해봤지만 요동치는 메모리는 돌아오지 않았다.

범인을 잡기 위해, Allocation Tracking을 해보니 용의선상에 없던 놈이 범인이었다. 범인은 앱에서 사용하던 버그 트래킹 툴(Splunk Mint)인데,  툴에서 Network IO를 Monitoring 하는 로직이 BufferedInputStream의 read시마다 실행되도록 구현되어 있어 속도가 빠른 네트워크를 통해 대용량 파일을 다운로드 할 때 해당 로직이 매우 빈번하게 실행된다.

15초간 Allocation Tracking한 결과는 아래와 같다. 눈을 크게 뜨고 보시라.

절대 현혹되지 마라

 

다행히 Network Monitoring을 비활성화 할 수 있도록 SDK가 구현되어 있어 비활성화 후 테스트하니 메모리는 다시 고요해졌다.

이렇게…

백투장판

 

 

금일의 교훈

  1. 몸에 좋은 약도 알고 먹자.
  2. Android Studio의 Monitoring을 통해 Profiling을 가끔해보자. 버그 같지 않은 버그를 잡을 수 있다.

[Android] Unit Test

태초에 사람이 완벽하기는 커녕, 전혀 믿을게 되지 못하기 때문에 우리는 테스트가 반드시 필요하다.

 

Android에는 크게 2가지의 테스트가 존재한다. 1. Unit Test, 2. Instrumentation Test.

* Unit Tests는 Development machine의 JVM에서 실행되는 테스트를 의미하고,

* Instrumentation Tests는 실제 기기에서 수행되는 테스트를 의미한다.

Unit Tests는 Android API 사용에 제한이 있는 단점이 존재하지만, Development machine에서 각각의 기능을 빠르게 테스트를 수행 할 수 있다는 장점이 있다.

 

Android Studio에서 Unit Tests를 작성하기 위해서는 먼저 build.gradle에 아래 2개의 dependencies를 추가해줘야 한다.

 

2개의 dependency를 추가한 뒤, Build Variants의 Test Artifact를 Unit Tests로 변경한다.

 

이제 필요한 테스트 함수를 src/test/java 밑에 추가한 뒤, 구현한 Business Logic들이 정상적으로 동작하는지 검증하면된다.

추가로 각각의 테스트 함수는 상호 의존성 없이 작성되어야 한다.

 

아래는 AES Encryption/Decryption이 정상적으로 동작하는지 검증하기 위해 작성한 함수다.

Unit Tests를 통해 정상적인 경우는 물론, 예상할 수 있는 예외상황이 미리 정의된 대로 처리가 되는지 검증 할 수 있다.

 

태초에 인간은 완벽하지 않다. 쏟아지는 버그 리포트에 당황하지 말고 미리미리 대비하자.

 

* References

http://tools.android.com/tech-docs/unit-testing-support

 

[Android] Activity Transition.

Activity 전환시의 Transition은 매우 중요하다.

신부감을 고르는 것만큼은 아니지만 오늘 점심에 김치찌개를 먹을지 돈까스를 먹을지 보다는 중요하다.

중요도에 비해 적용은 매우 쉽다. 거의 공짜다.

간단한 효과의 경우 4개의 .xml 파일과 2줄의 코드면 끝이다. OMG!!!

2015년 S/S에 유행하고 있는 현재 Activity를 Step Back 시키면서 새로운 Activity를 우측에서 꺼내오는 효과는

아래 4개의 .xml 파일로 처리한다.

(참고로 UI/UX의 트렌드 세터 Airbnb도 위의 효과를 여러군데서 적용하고 있다)

slide_in.xmlslide_out.xml은 호출되는 Activity에 적용될 효과고,

step_back.xmlstep_in.xml은 호출하는 Activity에 적용할 효과다.

 

4개의 .xml 파일을 res/anim 폴더에 만들었다면 이제 8부 능선을 넘었다.

이제 만들어 놓은 .xml 파일들을 Activity를 실행하는 시점과 종료하는 시점에 적용만 하면 된다.

 

실행하는 시점의 코드는 아래와 같다.

overridePendingTransition의 첫번째 파라미터는 enter animation이고, 두번째 파라미터는 leave animation이다.

즉, 실행되는 Activity는 slide-in으로 들어오고, 현재 Activity는 step-back으로 나가는 거다.

 

실행되는것 만큼 Activity가 종료될때의 효과도 중요한데, Activity가 실행될때의 효과를 반대로 적용해주는게 좋다.

 

Activity가 종료될 때, 기존의 Activity는 step-in 하면서, 현재 Activity는 slide-out 시키는 효과다.

 

이제 당신의 앱도 섹시하게 화면전환이 되는걸 확인 할 수 있다.

아무렴 그렇고 말고.

[Android] App Indexing Introduction.

App Indexing은 짧게 요약하면 Google Search의 검색 결과에 어플리케이션의 컨텐츠를 노출시키는 방법이다.

어플리케이션에서 App Indexing을 구성하는 방법은 아래 4단계를 거치면 된다.

 

1. App Indexing을 Project의 dependencies에 추가한다. (시작은 쉽다)

 

2.  Google Search의 검색 결과에서 앱이 바로 실행되기 위해서는 intent-filter가 필요하다. (너와 나의 연결고리 말이다.)

검색 결과에서 바로 실행 될 Activity에 Deep Linking을 위한 intent-filter를 추가한다.

아래 intent-filter는 http://radioinn.com/podcast로 시작하는 broadcast를 처리하겠다는 의미다.

 

3. 연결고리까지 만들었으니, 이제 어플리케이션이 어떤 컨텐츠를 갖고 있는지 증명해야한다.

어플리케이션에서 Google Search의 검색 결과에 추가하고 싶은 컨텐츠를 아래와 같이 추가한다.

Title의 경우 Google Search의 자동 완성에 표시될 이름이고,

ContentId의 경우 Google Search의 겸색 결과에서 앱을 실행시에 dataString에 포함될 값이다.

* 실행된 Activity에서는 ContentId를 통해 원하는 컨테츠를 보여줄 수 있어야 한다.

 

3번까지 정상적으로 성공했으면, Google앱의 Search에서 Title에 포함된 내용을 검색했을 때 아래와 같이 나와야 한다.

아래 이미지에서는 ‘윤종신 허지웅의 어수선한 영화이야기’가 App Indexing을 통해 Google Search에 포함된 경우다.

우오오!!!! 이렇게 간단하다니!!!!

2015-06-02 09.59.55

 

4. 이제 Google Search에서 검색 결과를 클릭했을 때의 처리만 남아있다.

이미 2번에서 Google Search의 검색 결과에서 클릭했을 때 실행을 위한 intent-filter는 추가했었다.

intent-filter가 정상적으로 추가되어 있다면, Google Search에서 검색 결과를 클릭했을 때,

앱이 실행중이면 onNewIntent(), 앱이 실행중이 아니면 onCreate()로 intent를 넘겨준다.

이제 넘겨받은 intent에서 ContentId를 파싱해서 컨테츠를 보여주면 된다.

끝. (이제 앱이 히트를 칠 일만 남았다)

 

* 참고자료

https://developers.google.com/app-indexing/introduction

– http://io2015codelabs.appspot.com/codelabs/app-indexing#1

Older posts

© 2017 Regular Motion

Theme by Anders NorenUp ↑