이클립스 프로젝트에 RoboGuice(RG) 2.0 설치하기
- 안드로이드프로젝트의 libs에 roboguice-2.0.jar, guice-3.0-no_aop.jar, javax.inject-1.jar 파일을 넣고 빌드패스에 추가
- RG 2.0에서는 RoboApplication 상속받은 Application을 작성해서 AndroidManifest.xml에 등록할 필요는 없음
Activity 작성
- RoboActivity 상속받은 Activity 작성
- @InjectView , @Inject 등의 어노테이션 사용
모듈 주입 커스터마이징
- AbstractModule 클래스를 상속받는 클래스 작성
- configure() 메소드에서 커스텀 바인딩 정의 : 자세한 구현은 Google Guice 문서 참조
- res/values/roboguice.xml에 아래처럼 컴스텀 모듈 등록
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="roboguice_modules">
<item>com.mypackage.MyModule</item>
</string-array>
</resources>
인스턴스 스코프
RG에 의해 생성 및 관리되어 다른 클래스에 주입되는 클래스의 인스턴스 스코프(생명주기) 설정
1. Singleton 스코프
- 앱에서 하나의 인스턴스만 존재
- 클래스에 @Singleton 어노테이션 선언 : Guice에서 제공
- 어떤 클래스에서 이 객체를 요청하든 동일한 인스턴스가 제공됨. 그러므로 쓰레드세이프하게 작성해야 함.
- Application 컨텍스트는 직접 주입 받을 수있음(특정 Activity, Service 등 current context랑 관계없는 global context)
- current context(액티비티 컨텍스트)를 주입받으려면 Provider<Context>를 사용해야 함
- 싱글턴 스코프를 가진 기본제공 모듈 : Application, ViewListener, Resources 등?
=> 그러나 RG에서 제공하는 대부분의 모듈은 context를 필요로 하므로 ContextSingleton 스코프를 갖는다.
- current context가 필요없거나 또는 Application 컨텍스트만 필요한 클래스에 적합
2. ContextSingleton 스코프
- current context(액티비티 컨텍스트)에 대해서 하나의 인스턴스만 존재
- 클래승 @ContextSingleton 어노테이션 선언 : RG에서 제공하는 스코프
- current context가 필요한 클래스는 ContextSingleton으로 선언
- 동일 액티비티 객체에 대해서 동일 인스턴스 제공(모든 액티비티에 대해서 동일 인스턴스 제공은 아님)
- Application, Context, Activity, Service 등 @Singleton/@ContextSingleton 클래스를 직접 주입받을 수 있음
- 컨텍스트싱글턴 스코프를 가진 기본제공 모듈 : Context, Activity, Service, AssetManager, ContentResolver,
LayoutInflator 및 기타 시스템서비스 모듈들
- current context가 필요한 클래스에 적합
3. 프로토타입 스코프
- 요청할 때마다 새로운 인스턴스 생성
- 클래스에 별도의 스코프 어노테이션 선언 없음. (프로토타입이란 용어는 제가 스프링에서 따온 것임)
- 주입될 때마다 또는 provider.get() 할 때마다 새 인스턴스가 생성됨
- 스코프가 설정돼있지 않고 public 기본생성자가 존재하는 모든 클래스가 가능
- Handler처럼 Provider에서 get() 요청시마다 새로운 인스턴스를 리턴하는 클래스
- context가 필요없고 상태를 가진 클래스에 적합
스코프 지정 방법
(1) 구현체 클래스에 @Singleton 붙임
(2) @Provides 붙은 메소드에 @Singleton 붙임
(3) bind().xxx().in(Singleton.class);
주요 기본제공 클래스의 스코프
- http://code.google.com/p/roboguice/wiki/ProvidedInjections
어떤 컨텍스트를 주입받을 것인가
- http://code.google.com/p/roboguice/wiki/InjectingContexts
- current context가 필요한게 아니라면 명시적으로 Application을 주입받아라
- Activity가 필요하다면 Activity를 주입받아라
- 잘 모르겠으면 Context를 주입받아라
Inject 되기 위한 생성자 조건
- 기본 생성자가 존재하거나
- Inject가능한 파라미터로만 구성되고 @Inject 선언된 생성자가 존재
@Inject
SomeClass(Context context, MyComponent component) {}
// 여기서 context와 component는 inject 가능해야함...
일반 POJO 클래스에 다른 객체들을 주입하는 방법
1. POJO 생성을 RG가 처리하는 경우
- POJO 내부의 @Inject로 선언된 멤버들은 자동 주입됨
- POJO 클래스가 RoboActivity를 상속받는 액티비티의 @Inject 멤버변수로 선언돼있는 경우 등
2. POJO 생성을 RG가 처리하지 않는 경우(개발자 또는 라이브러리에서 직접 생성하는 경우)
- POJO 생성자 등에서 RoboGuice.injectMembers(context, this)를 이용하여 수동으로 주입함
명시적인 injector 사용을 피하는 방법(생성자 등 초기화 메소드를 핸들링할 수 없는 경우)
- 클래스 또는 Provider, ContextScopedProvider를 static하게 inject 받음
- http://code.google.com/p/roboguice/wiki/HowToInjectXYZ
@Inject protected static ContextScopedProvider<T> tProvider; // T는 @ContextSingleton이어야함
@Inject protected static ExceptionHandler;//singleton
=> 단, MyModule에서 requestStaticInjection(POJO.class)을 해주어야 함
=> 그러나 RG 2.0에서는 static injection을 비권장 ( http://code.google.com/p/roboguice/wiki/UpgradingTo20 )
=> static injection은 context에 액세스할 수 없는 클래스 및 static 메소드를 가진 헬퍼나 유틸 클래스에 적합할 듯.
Provider란 무엇인가
- 인스턴스 생성이 복잡한 경우 인스턴스를 만드는 방법을 제공
- 예를들어 new MyPojo()로 객체 생성후 myPojo.init() 등의 추가 작업한 인스턴스를 리턴
- MyPojo를 주입받는 모듈은 초기화 완료된 MyPojo 인스턴스를 받게 됨
- Module에서 @Provides 어노테이션을 쓰는 메소드를 작성해도 됨(Provider 인터페이스 구현안해도 됨)
- http://code.google.com/p/google-guice/wiki/ProvidesMethods
명시적/묵시적 바인딩
- 명시적 바인딩 : Module에서 bind().to(), bind().toProvider()로 바인딩하는 것
- 묵시적 바인딩 :
(1) 기본생성자나 inject가능한 생성자를 가진 구현 클래스가 존재하는 경우
(2) @ImplementedBy를 통해 기본 구현체를 지정한 경우
(3) @ProvidedBy를 통해 구현체 인스턴스를 생성해줄 Provider를 지정한 경우
AOP 애스펙트에도 RG의 inject가 가능한가
- 가능함. Aspects.aspectOf()를 통해 aspect 싱글턴을 구하여 Guice 모듈에서 강제 inject시켜줌.
Injection 이후에 지정된 메소드 호출
- Guice의 TypeListener를 이용하거나 GuiceyFruit 또는 MyciaGuice의 @PostConstruct를 사용
- http://stackoverflow.com/questions/2093344/guice-call-init-method-after-instantinating-an-object
- http://code.google.com/p/mycila/wiki/MycilaGuice
- http://code.google.com/p/guiceyfruit/
RoboGuice 2.0 설정 방법 : http://code.google.com/p/roboguice/wiki/UpgradingTo20
'Android' 카테고리의 다른 글
[안드로이드] RoboGuice 단점 보완 방안 (0) | 2012.04.19 |
---|---|
[안드로이드] Non UI쓰레드에서 UI작업을 위한 올바른 Handler 생성법 (3) | 2012.04.19 |
[안드로이드] RoboGuice와 AndroidAnnotations에서 View 주입 및 Click 어노테이션 처리 위치 (0) | 2012.04.18 |
[안드로이드] RoboGuice 2.0 사용 환경에서 proguard 설정 (0) | 2012.04.16 |
[안드로이드] RoboGuice와AndroidAnnotations 비교 메모 (0) | 2012.04.16 |