cannot.find.zip.align= The zipalign tool was not found in the SDK.

SDK에 Android L과 함께 build-tools와 tools도 20.x 대로 업데이트가 되었다. 최신으로 업데이트 하고 나니 아래와 같은 에러가 뜬다.

(참고로 아래 에러는 인텔리제이 13 CE에서 나온 에러다)

zipalign내용은 zipalign 툴이 SDK 안에 없다며 SDK를 최신으로 업데이트 해보거나 zipalign을 수동으로 앱에 적용하라는 거다. 폴더를 확인해보면 tools\zipalign.exe가 안보이고 build-tools\20.0.0\zipalign.exe 안에 있다.

해결은 간단한데, build-tools\20.0.0\zipalign.exe을 복사해서 tools\ 폴더 안에 넣어주면 된다.

 

인텔리제이 커뮤니티에디션에 안드로이드 SDK 바로가기

안드로이드를 개발할 때 인텔리제이 기반의 안드로이드 스투디오를 많이 쓰지만, 인텔리제이 프로페셔널/커뮤니티 에디션(이하, 인텔리제이 IDE)에서도 안드로이드 개발이 가능하다. IDE에 기능들이 기본으로 포함되어 있고, 안드로이드 SDK의 AVD 매니저와 SDK 매니저 등의 바로가기도 지원한다.

Screen Shot 2014-07-20 at 1.18.57

그런데 처음 인텔리제이 IDE를 설치하면 저 메뉴가 보이지 않는다. 이 때는, 안드로이드 프로젝트를 먼저 하나 만들어 빌드를 하면 된다. 그 후, 확인해보면 위와 같이 Tools > Android > … 밑으로 메뉴가 생길 것이다.

하위호환성은 어떻게 지원하나?

안드로이드의 하위호환성/상위호환성에 대해서는 지난 글에서 설명한 바 있다. 이번에는 안드로이드에서 하위호환성을 어떻게 지원하는지 알아보자.

신규 모델에서 추가된 기능이라면 신규 모델에서만 실행되도록 앱을 설정한 후에 그 기능을 사용하면 된다. 개선된 기능이라면 오래된 모델에서는 개선 전의 것을 새로운 모델에서는 개선된 기능을 쓰면 그만이다. 성능이 개선될 수 있지만 동작은 할테니까 말이다. 하지만, UI와 같이 사용자가 위화감을 가질만한 부분은 어떻게 해야할까? 오래된 단말에 맞추어 개발을 하면 최신 트렌드에 맞지 않을 테고, 최신 단말에 맞추어 개발하면 오래된 단말에서 올바로 보일리가 없다. 이를 어찌해야하나?

안드로이드에서는 서포트 라이브러리(Support Library)라는 이름의 라이브러리들로 하위호환성을 지원한다.

서포트 라이브러리(Support Library)

처음 이 라이브러리가 릴리즈 될 때 이름은 안드로이드 호환성 라이브러리(Android Compatibility Library) 였다. 이름에서도 알 수 있듯이 이 라이브러리의 용도는 호환성 지원이다.

현재 v4, v7, v8, v13로 총 4개의 라이브러리가 있다. 각각 API 4, API 7, API8, API 13이상을 지원한다. 그러므로 minSdkVersion을 사용하고자 하는 라이브러리의 지원 버전 이하로 맞춰야 한다.

예를 들어 v7를 사용하고자 한다면,

<uses-sdk android:minSdkVersion="7" android:targetSdkVersion="17" />

와 같이 적어주어야 한다. 각 라이브러리들이 어떤 기능을 지원하는 지는 여기를 보면 된다.

사실 서포트 라이브러리가 하위호한성을만을 위한 라이브러리는 아니지만(이 라이브러리에서만 지원하는 기능도 있음) 대부분의 기능들이 UI(User Interface), 접근성(Accessibility), 레이아웃에 관련된 기능이라 호환성을 위한 라이브러리라고 봐도 무방하다.

안드로이드에서는 v4와 v7이 다양한 안드로이드 버전과 UI 관련 기능을 지원하기 때문에 사용을 추천하고 있으며, 이 때 v4와 v7 모두를 앱에서 사용했다면 minSdkVersion=7이 되어야 한다. 왜냐하면, minSdkVersion을 4로 설정하는 경우 v7 라이브러리가 동작하지 않기 때문이다.

마지막으로 소스코드 보호와 함께 필요없는 클래스들이 apk안에 포함되지 않도록 프로가드(ProGuard)를 사용하는 것을 권유하고 있다.

참고

  • http://developer.android.com/tools/support-library/index.html
  • http://developer.android.com/tools/support-library/features.html
  • http://developer.xamarin.com/guides/android/platform_features/fragments/part_4_-_providing_backwards_compatibility_with_the_android_support_package/
  • http://developer.android.com/guide/topics/manifest/uses-sdk-element.html

안드로이드 ANR 분석

ANR이란 무엇인가?

Application Not Responding의 약자이다. 단어 그대로, 어플리케이션이 응답하지 않는 경우 안드로이드 시스템에서 보여주는 에러이다. 메인 스레드(일명, UI 스레드)가 일정시간 동안 잡혀 있으면 발생한다.

언제 ANR이 발생하는가?

안드로이드 운영체제는 홈페이지 정리가 매우 잘 되어 있다. ANR의 경우는 여기에 정리되어 있는데,

  • 터치를 통한 사용자 입력이 5초 내에 처리되지 않았을 때
  • 브로드캐스트가 10초 내에 처리되지 않았을 때

가 나와있다. 하지만 여기에 나오지 않은 경우가 하나 더 있다.

  • 서비스가 20초 내로 처리되지 않을 때

안드로이드는 UI가 없는 컴포넌트인 브로드캐스트 리시버와 서비스도 메인 스레드에서 돌아가기 때문에 당연히 서비스에서도 시간 소모성 작업을 하는 경우 ANR이 발생할 수 있다.

왜 ANR이 발생하는가?

위의 ANR이 발생하는 조건을 보면 알겠지만, 앱이 무한 루프에 빠지거나 OOM(Out Of Memory)가 나야 ANR이 발생하는 것이 아니다. 시간이 좀 걸리는 처리를 해도 ANR이 충분히 발생할 수 있다. 그래서, 나처럼 자바프로그래밍에서 안드로이드로 온 사람에게는 한참동안 이해가 안될 수도 있다.

ANR이 필요한가?

ANR이 필요한 이유는 무엇인가? 내 생각에 이 부분을 이해하기 위해서는 사용자가 어떤 경우 문제가 있다고 느끼는가에 대한 것을 먼저 생각해야한다. 지금 대부분의 어플리케이션에서 사용하고 있는 프로그레스바를 생각하면 쉽다. 사용자에게 ‘움직이고 있다.’라는 사인을 주면 사용자는 기다린다. 하지만, 일명 먹통이 되면 사용자는 문제가 있다고 판단하여 전원을 끈다던가 다른 자신이 할 수 있는 해결책을 시도하는 것이다. 모바일 OS는 화면이 작아, 대부분(테블릿은 화면이 크고, 안드로이드에서 지원하는 프레그먼트는 한 화면에 여러개의 액티비티를 동작하게 할 수도 있다.)은 전체 화면을 차지한다. 이 때 화면이 정지한다면 정상적으로 동작하고 있음에도 문제가 있다고 느낄 수 있는 것이다.

그럼 어떻게 ANR을 관리해야 할까?

안드로이드 개발자 사이트를 참조해야할 질문이다. 여기에 잘 정리되어 있다. 간단히 요약하면,

  • 시간이 오래걸리는 작업은 스레드를 통해 처리하도록 권장한다.
  • 사용자에게는 프로그레스바 등을 이용해 진행 과정을 안내해 기다리도록 한다.
  • 이를 위해, 안드로이드에서 상속받아 사용할 수 있는 다양한 방법을 제공하고 있다.

dumpstate에서 ANR의 원인을 분석하고 싶다면?

SYSTEM LOG에서 ActivityManager가 ANR 메시지를 표시하지 않는지 살펴보자. “ANR in”으로 검색하면 된다.

12-31 11:28:40.489  3574  3627 E ActivityManager: ANR in com.androd.calendar (com.android.calendar/.MainActivity)
...
12-31 11:28:40.489  3574  3627 E ActivityManager: Reason: Input dispatching timed out (Waiting to send non-key event because the touched window has not finished processing certain input events that were delivered to it over 500.0ms ago. Wait queue length: 58. Wait queue head age: 20502.0ms.)
...

12-31 11:28:40.489  3574  3627 E ActivityManager: CPU usage from 4928ms to 328ms ago:
...

문제가 발생한 곳의 위치가 표시되고, 이유와 함께 CPU 사용량도 표시된다.

SYSTEM LOG에서 “SIG: 9″를 검색해 보자.  이는 시스템에서 ANR을 발생시키는 프로세스를 종료하기 위해 SIGNAL_KILL을 호출되면서 남기는 로그일 수 있다. 그 부분의 전후 로그를 살펴보자. ANR이라고 판단한 이유가 로그로 남아있을 수 있다.

EVENT LOG에서 “am_anr” 태그로 검색해 보자. anr이 발생한 어플리케이션 정보를 얻을 수 있다.

12-31 11:28:40.489  3574  3627 I am_anr  : [0,3669,com.android.calendar,952647237,Input dispatching timed out (Waiting to send non-key event because the touched window has not finished processing certain input events that were delivered to it over 500.0ms ago.  Wait queue length: 58.  Wait queue head age: 20502.0ms.)]

문제가 발생한 패키지 명과 PID, 이유가 표시된다.

DUMP OF SERVICE… 의 VM TRACES AT LAST ANR 부분에도 살펴보자. 문제가 없는 경우라면 다음 처럼 아무 내용이 없다.

...
WINDOW MANAGER LAST ANR (dumpsys window lastanr)
  <no ANR has occurred since boot>
...

하지만, ANR이 발생한 경우에는 아래와 같이 앱 정보부터 시작하여 실행 당시의 콜스택이 남아있다.

------ VM TRACES AT LAST ANR (/data/anr/traces.txt: 2017-01-22 01:48:03) ------

----- pid 16287 at 2017-01-22 01:47:25 -----
Cmd line: com.facebook.orca
...

콜 스택을 확인할 때에는 “main” 스레드부터 찾자. 글의 초반에 설명했듯이 ANR의 원인이 메인 스레드(일명 UI 스레드)이 오랫동안 바쁜 경우이므로 “main” 스레드 정보를 먼저 확인해야 한다. 특히, TIMED_WAIT나 MONITOR 에 있는지 확인하자.

그 밖에

ANR이 Activity Manager나 Window Manager 같은 곳에서 발생한 경우는 “어플리케이션이 응답이 없습니다. 기다리시겠습니까?”와 같은 메시지가 표시되지 않을 수 있다.

참조

Android AVD의 proxy 설정 방법

방법은 2가지다.

하나는 에뮬레이터를 실행할 때, 다른 하나는 AVD가 실행된 후에다. 아래에 두가지 방법을 소개한다.
1.

emulator -avd [avd name] -http-proxy http://[proxy-server-ip]:[port]

2.

  1. Menu
  2. Settings
  3. Wireless & Networks
  4. Mobile Networks
  5. Access Point Names
  6. “Telkila Internet” 클릭
  7. “proxy”와 “port”를 입력
  8. (필요하다면) “username”, “password”도 입력

이런 데이터는 모두 Android Developer 사이트에 있다는 사실도 있지말자. 여기를 참조하자.

그 밖에 다른 proxy 설정 방법을 찾고 있다면, Stackoverflow에 올라온 다른 답변을 참고하자.

참조