티스토리 뷰

 Android Support library 19.1에 추가된 Android annotations을 소개합니다. 가장 최신버전의 Support library는 현재 21.0.3입니다.

 

이 글은 아래 사이트들을 참고하여 작성하였습니다.

  Java annotation : http://en.wikipedia.org/wiki/Java_annotation

  Android annotations http://tools.android.com/tech-docs/support-annotations



Annotations이란?

 - Annotation은 Java 코드에서 사용가능한 syntactic metadata를 말한다.

 - classes, methods, variables, parameters, 패키지에서 사용이 가능.


 기본적으로 Java에서 제공되는 Annotations 이외에 커스텀하여 사용하는 많은 Annotations이 존재합니다. 이번 글에서는 이중 Android Support library 19.1에서 추가된 Annotations을 소개합니다.


 

Java에서 제공되는 Annotations(참고 : http://en.wikipedia.org/wiki/Java_annotation)

 - @Override : 함수 override일 경우 사용되는 Annotations (가장 흔하게 볼 수 있죠.)

 - @Deprecated : 해당 변수, 함수명이 삭제될 수 있음을 나태낼때 사용합니다.

 - @SuppressWarnings : 권장하지 않는 구문에 대하여 노랑색으로 경고를 표시해주는 경우가 있습니다. 이경우에 사용하는 Annotations에 해당됩니다.

 - @SafeVarargs : Java 7에 추가된 Annotation

 - @FunctionalInterface



Android Support library의 Annotations

 Support library 19.1부터 사용이 가능하며, 추가된 Annotations은 아래와 같습니다. 작성 순서는 아래와 같습니다. 가장 유용해 보이는 순서대로 작성해보았습니다.

 아래 Annotations들은 get/set 함수에 모두 사용이 가능합니다.

  • Resouce Type Annotations
  • IntDef and StringDef Annotations
  • Nullness Annotations

간단하게 Sample 프로그램과 Annotations을 사용하였을 경우 오류 표시 내용을 다루어보겠습니다.



Android Annotations 사용법

 build.gradle에 아래와 같은 코드를 추가해주시면 됩니다. Android studio의 경우에는 sync을 하면 사용이 가능해집니다.

dependencies {

   compile 'com.android.support:support-annotations:20.0.0'

}



Resource Type Annotations

 res 폴더 아래에 정의되는 모든 res가 정말 정의되어 있는 res인지, 그리고 String resource를 정말 불러오고 있는지를 미리 검증할 수 있는 Resource Annotations입니다.

 @StringRes

 @LayoutRes

 @ColorRes

  ...

위와 같이 정의되어 있는 Annotations이 많이 있습니다. 이름은 자신이 사용해야할 폴더(리소스 명) + Res만 붙여주면 정의되어있는 Android Annotations이 표시됩니다.


 이 Resource Type Annotations은 해당 Resource 값만 받아서 처리해야할 경우에 유용합니다. String인데 color resource를 정의하면 당연히 오류가 나게 됩니다. 이를 코딩상에서 미리 방지하기위한 Annotations입니다. 사용법은 아래와 같습니다.

public class MainActivity extends ActionBarActivity {


    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);


        String text = getResources().getString(getTextResource());

    }


    @StringRes

    private int getTextResource() {

        return R.string.intro;

    }

}


 안드로이드의 기본 함수에서도 해당되는 Resource가 아니라면 아래와 같이 오류가 표시됩니다. layout type이 아니라는 오류가 발생하고, 제가 정의한 @StringRes는 string type이 아니라는 오류가 발생합니다.



 만약 Annotations을 정의하지 않으면 아래와 같이 될 수 있고, 실제 실행을 해야만 오류가 발생함을 확인할 수 있겠습니다. 미리 오류를 대비하기 위한 Annotations으로 추천드립니다.



 Resources type annotations을 정의하게되면 위와 같은 오류를 미연에 방지할 수 있으니 전 여기에 소개할 3개의 Annotations 중 이를 가장 추천합니다.



IntDef and StringDef Annotations

 IntDef와 StringDef는 정의되어 있는 변수를 제외한 다른 값을 사용하지 못하게 하기위한 Annotations입니다. enums과 동일합니다. Int와 String에 대한 정의를 하고, 이만 사용하도록 설정하는 것이죠.


 아래와 같은 예제를 참고하면 정의해야하는 부분은 많지만 내가 정의한 값외에 사용하지 못하게 처리할때는 가장 좋은 Annotations라고 생각됩니다.

 - @IntDef, @StringDef를 정의합니다. @IntDef({ value, ... })을 정의

 - @IntDef, @StringDef를 맵핑하여 사용할 @interface 정의합니다. 실제 사용할때는 @{@interface}이름을 사용

 - setType과 getType method를 참고하면 @KeyType을 사용

public class MainActivity extends ActionBarActivity {


    private int type;


    public static final int KEY_ONE = 1;

    public static final int KEY_TWO = 2;


    @IntDef({KEY_ONE, KEY_TWO})

    public @interface KeyType{}


    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);


        setType(KEY_ONE);

    }


    public void setType(@KeyType int type) {

        this.type = type;

    }


    @KeyType

    public int getType() {

        return type;

    }

}



 이를 사용하면 정의되어 있는 값의 변수명을 입력해야합니다. 직접 숫자 1, 2, 3을 넣으면 아래와 같이 정의되어있지 않다는 내용의 오류가 발생하게됩니다. 그러므로 정의되지 않는 값을 받아 들이지 않도록 처리하는데 있어서 가장 좋은 방법에 해당됩니다.



 이는 @StringDef 역시 동일하게 처리가 가능합니다.



Nullness Annotations
 Nullness annotations는 2개의 Annotations이 있습니다.

 @NonNull : null을 허용하지 않을 경우

 @Nullable : null을 허용할 경우

 

 아래 예제코드는 @NonNull과 @Nullable을 모두 사용한 예제입니다. setText 함수에서 TextView에 값을 셋팅하는데 이때 NonNull을 붙여주면 이 함수에 String text 변수는 null을 허용하지 않음을 뜻합니다.

public class MainActivity extends ActionBarActivity {


    private TextView textView;


    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);


        textView = (TextView) findViewById(R.id.text);


        String text = getText();

        setText(text);

    }


    private void setText(@NonNull String text) {

        textView.setText(text);

    }


    @Nullable

    private String getText() {

        return null;

    }


}



return 함수에 null을 허용할 경우

 return 함수에서도 Nullness Annotations을 적용할 수 있습니다. 아래 함수는 text를 return 하는 함수입니다. 이때 아래와 같이 @Nullable을 추가하면 위에서 봤던것과 반대로 null을 허용하는 return을 가지게 됩니다.

    @Nullable

    private String getText() {

        return null;

    }


@NonNull에 null을 추가하게되면 아래와 같이 경고 메시지가 표시됩니다. 개발에 있어서 null을 허용하거나, null을 허용하지 않을 경우에 대하여 미리 Annotations을 적용하여두면 추후 개발에 문제가 줄어들 수 있습니다.



마무리

 간단하게 Android의 Support library에 정의된 Annotations을 살펴보았습니다. 3가지 Annotations을 잘 사용하면 코드상 문제가 되는 부분을 많이 줄일 수 있으며, 사전에 오류를 걸러낼 수 있어서 좋습니다.

 감사합니다.



댓글