기본 콘텐츠로 건너뛰기

2022 08 26 회사 워크샵

Lint API Check


Lint API Check

posted Feb 15, 2012 2:54 PM by Tor Norbye


 ADT 가 17 버전으로 업데이트 되면서 Lint 툴에도 많은 향상이 이루어졌습니다. 체크하는 항목 수가 두배 가까이 증가하였으며, 기본 구조도 많이 개선되었습니다. 이제 Lint 툴은 자바 소스 뿐만아니라, 컴파일된 바이트 코드도 분석합니다. 덕분에, 새로운 종류의 문제들을 사전에 감지 할 수 있게 되었습니다.

 한 가지 예를 들어 볼까요? 만일 여러분이 API 4 (안드로이드 1.6) 버전을 지원하는 어플리케이션을 작성하기로 마음먹었다고 상상해보세요. 아마 메니페스트에는 다음과 같이 값이 설정될 것 입니다.

   <uses-sdk android:minSdkVersion="4" />

 그리고 Lint 툴을 돌려 보면 아마 다음과 같은 에러가 발생할 수도 있습니다.


src/com/example/android/apis/app/Animation.java:70: Error: Call requires APIlevel 5 (current min is 4): android.app.Activity#overridePendingTransition [NewApi]
    overridePendingTransition(R.anim.zoom_enter, R.anim.zoom_exit);
    ^

src/com/example/android/apis/animation/AnimationCloning.java:80: Error: Callrequires API level 11 (current min is 4): android.animation.ObjectAnimator#ofFloat [NewApi]
    ObjectAnimator anim1 = ObjectAnimator.ofFloat(balls.get(0), "y",
                                          ^

res/layout/switches.xml:35: Error: View requires API level 14 (current min is 4): <Switch> [NewApi]
    <Switch android:id="@+id/monitored_switch"
    ^

 여러분이 보시는 바와 같은 Lint 툴은 이제 안드로이드 버전 별로 호출 가능한 전체 API 에 대한 데이타베이스를 갖고 있으며, 어떤 API 가 어떤 버전에서 새롭게 추가된 API 인지 여러분에게 알려 줄 수 있습니다. 그리고 메니페스트에 선언된 API 레벨에서 지원하지 않는 API 를 발견하게 되면, 위와 같은 경고 메세지를 출력해 줍니다. (이전에는 디바이스에 런타임으로 실행 시, Unresolved Symbol 같은 오류가 발생했습니다.)

 물론 여러분이 타켓으로 삼은 API 레벨과 동일한 SDK 를 이용하여 어플리케이션을 개발하고 있다면, 위와 같은 경우 컴파일 타임에, 알 수 없는 API 라는 에러가 발생할 것 입니다. 하지만 이런 방식에는 단점이 있습니다. 특히나 여러분이 가능한 경우에는 새로운 안드로이드 버전의 API 를 사용하고자 하는 경우에는 더욱 그렇습니다. 만일 예전 버전의 SDK 를 로드한 후, 새 버전의 API를 호출하기 위해서는 매번 Reflection 패키지를 이용해 API 및 클래스 이름을 통해 해당 기능을 활용해야 합니다. 결코 권장할만한 방법이 아닙니다.

 따라서 많은 개발자들은 비록 구 버전의 안드로이드를 대상으로 하는 어플리케이션을 개발하는 경우에도 새버전의 SDK 를 활용합니다. 새로운 API 를 손쉽게 호출 할 수 있지만, 대신 해당API 가 옛 버전에서 잘못 호출되지 않도록 (그래서 앱이 죽어버리지 않도록) 런타임시에 실재로 호출 가능한지 확인하는 코드를 추가할 필요가 있습니다.

 하지만, 언제나 개발자는 실수할 가능성이 있으며 (버전 체크를 깜박하는 등), 새로운 Lint 툴이 바로 이런 실수를 예방할 수 있게 도와줍니다.

 그렇다면 만일 여러분이 올바른 환경하에서만 호출되도록 주의 깊게 작성한 코드는 어떻게 처리하면 될까요? 이경우 해당 코드에 새로운 @TargetApi annotation 을 이용하여, 어떤 버전에서 해당 코드가 동작하는지 명시하면, Lint 툴은 해당 부분을 감안하여 검사를 진행합니다. (@TargetApi 를 붙였다고 해서, 런타임에 오류가 발생하지 않는 것은 아닌점에 주의하세요.)

private void createAnimation() {
if (animation == null) {
      @TargetApi(11)
            ObjectAnimator anim1 = ObjectAnimator.ofFloat(balls.get(0), "y",
                        0f, getHeight() - balls.get(0).getHeight()).setDuration(500);
            ObjectAnimator anim2 = anim1.clone();
            anim2.setTarget(balls.get(1));
            anim1.addUpdateListener(this);
 만일 전체 메서드나 전체 클래스가 새로운 API 버전에서만 동작한다면, 다음과 같이 @TargetAPI annotation 을 지정 할  수 있습니다.


import java.util.ArrayList;

@TargetApi(11)
public class AnimationCloning extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
 Lint 툴의 이 새로운 기능이 숨겨진 버그를 발견하는데 도움이 되길 바랍니다~

------------------------------------------------------------------------------------------
 ADT 17 버전에 새롭게 추가된 유용한 기능들을 한번 소개해 봐야지 하고 생각만 하고 있던 사이에, 벌써 ADT 18 버전이 릴리즈 되었네요ㅠㅠ. 17버전에서 추가된 기능 중, 소스의 특정 부분이나 메서드, 클래스가 특정 API 버전에서만 동작하도록 지정하는 @TargetApi 를 소개하는 글을 번역해 보았습니다;;; 조금 늦은 감이 있지만 도움이 되시길 바랍니다.




[출처] http://huewu.blog.me/110136168928

댓글