AspectJ 문서에는 아래와 같이 @within()과 @annotation()에 대해 설명합니다.



즉, Anno라는 어노테이션에 대해서(제가 제대로 해석했다면...)


- @within(Anno) : Anno 어노테이션을 갖는 타입(클래스) 안에 정의된 코드와 관련된 조인포인트

- @annotation(Anno) : 조인포인트 대상이 Anno 어노테이션을 갖는 조인포인트


http://whiteship.tistory.com/379 에서는 이렇게 설명합니다.


- @within(Type) : 선언된 타입에 @Type 어노테이션이 붙어있을 때 그 객체의 모든 execution Join point를 나타냅니다.

- @annotation(Type) : 실행되는 메소드에 @Type 어노테이션이 붙어있을 때 그 메소드의 execution Join point를 나타냅니다.


http://www.egovframe.org/wiki/doku.php?id=egovframework:rte:fdl:aop:aspectj 에서는 이렇게 설명하네요.


- @within(Transactional) : 대상 객체의 선언 타입이 @Transactional 어노테이션을 갖는 모든 결합점

- @annotation(Transactional) : 실행 메소드가 @Transactional 어노테이션을 갖는 모든 결합점



그러니까 @within()은 어노테이션이 붙은 클래스에 적용되고, @annotation()은 어노테이션이 붙은 메소드에 적용된다고 심플하게 이해하고 사용하면 될듯합니다만, 정확히 하자면 @annotation()은 조인포인트가 클래스건 메소드건 따지지 않는 것으로 보입니다.


(1) @annotation(Anno) && within(my.aop.*)

=> my.aop 패키지의 클래스 중에서 Anno 어노테이션이 붙은 클래스


(2) @annotation(Anno) && within(my.aop.*) && execution(* test*(..))
=> my.aop 패키지의 클래스에 정의된 test* 메소드 중에서 Anno 어노테이션이 붙은 메소드

(3) @annotation(Anno) && execution(* test*(..)) 
=> test* 메소드 중에서 Anno 어노테이션이 붙은 메소드

(4) @annotation(Anno) && @within(Anno) && execution(* test*(..))
=> Anno 어노테이션이 붙은 클래스의 test* 메소드 중에서 Anno 어노테이션이 붙은 메소드


대충 감이 오네요.


참고로 @annotation(Anno) && execution(* test*(..)) 포인트컷은 이렇게도 표현할 수 있습니다.

  

execution(@Anno * test*(..))




Posted by 에코지오
,

AndroidAnnotations 라이브러리와 비교하여 RoboGuice의 단점으로 지적되고 있는 사항을 해결하기 위한 방안입니다.



런타임시에 리플렉션(reflection) 사용에 따른 성능하락

- 스마트폰 하드웨어 성능이 점점 강해지고 있으므로 앞으로 큰 문제는 안될 것임

  또한 Dalvik VM의 리플렉션 성능이 점점 좋아지고 있음

- 게임처럼 대부분의 기능이 스마트폰 내에서 처리되는 앱이라면 문제될 수 있음

  그러나 주로 네트워크를 통해 서버측에서 결과를 받아 단순히 표출하는 클라이언트 앱의 경우에는 

  응답시간의 대부분은 네트워크 소요시간이 차지하며, 폰 로컬의 리플렉션 처리가 차지하는 시간은 매우 작을 것으로 판단됨. 

  따라서 클라이언트 앱에서 RoboGuice의 런타임 리플렉션은 큰 문제가 아님.



앱 용량이 많이 커지는 문제

- RoboGuice를 사용하기 위해 필요한 guice-3.0.jar 파일과 roboguice-2.0.jar 파일의 크기를 합치면 거의 820KB임.

- 반면, androidannotations-2.5.jar 파일은 53KB에 불과함

- 그러나 실제로 apk의 용량이 820KB만큼 커지는 것은 아니며 ProGuard를 적절히 설정하면 apk 파일 크기가 생각보다 많이 늘어나지 않음



RoboActivity 상속에 따른 Activity 클래스의 유연성 부족

- AndroidAnnotations에는 Activity에 @EActivity 어노테이션을 선언만하면 되기 때문에 Activity가 다른 액티비티를 상속받는 것이 가능함

- 그러나 RoboGuice에서는 RoboActivity를 상속받아야 하므로 다른 액티비티를 상속받을 수 없음

- 따라서 AOP를 통해서 다른 액티비티를 상속받지 않고도 기능을 추가할 수 있는 방법을 적용하는 것을 고려



유틸리티성 어노테이션 부족

- AndroidAnnotations는 @ViewById 같은 injection용 어노테이션 외에 @Click, @Rest, @Background, @UiThread 등의 다양한 유틸리티성 어노테이션을 제공함

- 반면 RoboGuice는 코드를 줄여주는 이러한 유틸리티가 별로 없음

- AndroidAnnotations 소스를 참고하여 유틸리티성 어노테이션을 처리하는 AOP 애스펙트를 개발하여 적용하면 됨(별로 어렵지 않음)

- @Click : (공통) 액티비티의 setContentView() 메소드에 after 어드바이스로 처리

- @Background, @UiThread : 메소드에 around 어드바이스로 처리

- @Rest : ... 고민중...






Posted by 에코지오
,

UI 쓰레드가 아닌 일반 쓰레드에서 UI 작업처리를 위해 new Handler() 를 통해 Handler를 사용할 경우 아래와 같은 에러가 발생합니다.


java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()


그럼 UI처리를 위한 Handler는 UI 쓰레드에서만 생성해야 한다고 생각할 수 있습니다.

http://huni.springnote.com/pages/5402287



그러나 그렇지 않습니다. 임의의 쓰레드에서도 UI작업용 Handler를 사용할 수 있습니다.

http://blog.naver.com/PostView.nhn?blogId=rgjoon&logNo=90094338577



다만, UI 작업을 처리하기 위해서는 아래와 같이 UI쓰레드에 바인딩된 Handler를 만들어야 합니다.

http://stackoverflow.com/questions/6369287/accessing-ui-thread-handler-from-a-service


Handler handler = new Handler(Looper.getMainLooper());




* 참고

http://www.aviyehuda.com/2010/12/android-multithreading-in-a-ui-environment/

http://babtingdev.tistory.com/276


Posted by 에코지오
,