githuab地址:
https://github.com/roboguice/roboguice/wiki/InstallationGradle
https://github.com/google/guice/wiki
其中3.0之后没有的方法EventManager的fire(),RoboApplication (2.*之后就没了),还有就是设置model,现在好像只能通过xml文件中设置。
Android studio设置
在对应的model的dependencies添加如下:
compile 'org.roboguice:roboguice:3.+'
provided 'org.roboguice:roboblender:3.+'
再添加一个新的project.dependencies ,也是在model的build.gradle中添加
project .dependencies {
// For the optional Nullable annotation
compile 'com.google.code.findbugs:jsr305:1.3.9'
}
这样子就可以使用RoboGuice
首先,RoboGuice是一个注入框架,跟AndroidAnnotation,Dragger,ButterKnife一样,是简化我们的代码,带来方便的。
使用:
Activity中使用,Activity需要继承RoboActivity
1,为Activity使用布局
@ContentView 示例
@ContentView(R.layout.activity_main)
public class MainActivity extends RoboActivity {
.....
}
为View初始化,使用@IntjectView
@InjectView(R.id.textview)
private TextView tv;
资源:@InjectResource所有德邦res目录下的资源都可以通过如下方式找到,比如动画,String,color,像素等
@InjectResource(R.string.app_name)
String name;
获取系统的一些系统服务,通过@Inject标签完成初始化
@Inject Vibrator vibrator;
@Inject NotificationManager notificationManager;
包括:
@Inject ContentResolver contentResolver;
@Inject AssetManager assetManager;
@Inject Resources resources;
@Inject LocationManager locationManager;
@Inject WindowManager windowManager;
@Inject LayoutInflater layoutInflater;
@Inject ActivityManager activityManager;
@Inject PowerManager powerManager;
@Inject AlarmManager alarmManager;
@Inject NotificationManager notificationManager;
@Inject KeyguardManager keyguardManager;
@Inject SearchManager searchManager;
@Inject Vibrator vibrator;
@Inject ConnectivityManager connectivityManager;
@Inject WifiManager wifiManager;
@Inject InputMethodManager inputMethodManager;
@Inject SensorManager sensorManager;
@Inject Application application;
@Inject Context context;
@Inject +类名+变量 进行初始化
有几种情况
1,这个类没有构造器,比如
import android.util.Log ;
import com.google.inject.Inject ;
/**
* Created by user on 2015/11/18.
*/
public class Bar {
private int agr;
private int getAgr ()
{
return agr;
}
public void setAgr()
{
this .agr = agr;
}
}
2.全部的构造器没有添加@Inject,然后还带有一个空的构造器
比如上面代码添加
public Bar()
{
}
public Bar(int a)
{
this .agr = a ;
}
3,构造器中的参数列表不带有基本数据类型,然后有一个构造器,是使用@Inject指定
比如下面,被调用的就是使用了@Inject的构造器,但是没有东西传入了,这种情况下,有没有空的构造器也是可以的(没有使用Named注解的时候)
package retrofit.com.example.user.roboguicedemo ;
import android.util.Log ;
import com.google.inject.Inject ;
/**
* Created by user on 2015/11/18.
*/
public class Bar {
private String agr;
private String name;
@Inject
public Bar(String a)
{
this .agr = a ;
Log. i("TAG", "被调用,但是传入来的" +agr) ;
}
public Bar(String a,String b)
{
this .agr = a ;
this. name = b;
}
public String getAgr() {
return agr;
}
public void setAgr(String agr) {
this .agr = agr ;
}
public Bar()
{
}
public String getName() {
return name;
}
public void setName(String name) {
this .name = name ;
}
}
其中,使用时候的调用时
@Inject
private Bar bar ;
即可完成初始化
这样子就完成了初始化
还有,我们可以自己为一个类使用注解添加空构造器,
就是
class MyActivity extends RoboActivity {
@Inject Foo foo; // this will basically call new Foo();
}
即可
但被使用的时候,就会自动调用空的构造器了
单例模式:@singleton,这样子声明就是一个单例了,可能会内存溢出(直到应用被销毁才会被回收)
@Singleton //a single instance of Foo is now used though the whole app
class Foo {
}
使用一个上下文的单例@ContextSingleton,,这样子的变量实例的生命周期就跟他所在的上下文相关联了,上下文一般是四大组件或者是Application中使用存在
比如
public MyActivity extends RoboActivity {
@Inject Foo foo;
@Inject Bar bar;
}
public class Foo {
@Inject Bar bar;
}
@ContextSingletonpublic class Bar {
}
然后
new MyRoboActivity().foo != new MyRoboActivity().foo;//上下文不一样
MyRoboActivity a = new MyRoboActivity();
a.bar == a.foo.bar//上下文一样
注意一定:在不同的Fragment中使用,然后这些Fragment绑定到相同的Activity的时候,他们的单例还是存在效果,就是还是一样的。
还有一种方式,就是通过bind的时候制定单例,
比如
bind(TransactionLog.class) .to(InMemoryTransactionLog.class) .in(Singleton.class);
这样子,就可以不要上面的那个@ Singleton注解了
自定义binding
就是使用子类的多态
比如现在是这样子,有一个父类(可以是接口,可以使实现或者抽象类)
public interface IFoo
{
void printName();
}
子类
public class Foo1 implement IFoo
{
@override
public void printName()
{
Log.i("TAG","i am Foo1");
}
}
//
public class Foo2 implement IFoo
{
@override
public void printName()
{
Log.i("TAG","i am Foo2");
}
}
然后,binding,自定义一个继承AbstractModule的类
然后,在里面的configure中进行绑定
示例代码:
package retrofit.com.example.user.roboguicedemo ;
import com.google.inject.AbstractModule ;
import com.google.inject.Binder ;
import com.google.inject.Scopes ;
import com.google.inject.Singleton ;
import com.google.inject.binder.AnnotatedBindingBuilder ;
import com.google.inject.name.Named ;
import com.google.inject.name.Names ;
/**
* Created by user on 2015/11/18.
*/
public class MyModule extends AbstractModule {
@Override
protected void configure() {
Binder binder = binder();
//前面是接口父类,后面是子类
binder.bind(IFoo.class).annotatedWith(Names. named( "Foo1")).to(Foo.class );
binder.bind(IFoo.class).annotatedWith(Names. named( "Foo2")).to(OtherFoo.class );
// bind(IFoo.class).toInstance(new Foo());
}
@Override
protected <T> AnnotatedBindingBuilder< T> bind (Class<T> clazz) {
return super .bind(clazz);
}
}
然后在清单文件中的applica中添加(是在application节点中添加)
<meta-data android:name="roboguice.modules"
android:value="retrofit.com.example.user.roboguicedemo.MyModule" />
使用:
@Inject
@Named("OtherFoo") //对应Foo2
IFoo ifoo;
@Inject
@Named("Foo")//对应Foo1
IFoo iFoo;
这样子,对应的变量调用printName()方法就可以调用到对应的方法了
还有一种实现方式是自定义注解
自定义注解:
package retrofit.com.example.user.roboguicedemo ;
import com.google.inject.BindingAnnotation ;
import java.lang.annotation.Documented ;
import java.lang.annotation. ElementType;
import java.lang.annotation.Inherited ;
import java.lang.annotation.Retention ;
import java.lang.annotation.RetentionPolicy ;
import java.lang.annotation.Target ;
/**
* Created by user on 2015/11/18.
*/
@BindingAnnotation
@Retention(RetentionPolicy. RUNTIME)
@Documented
@Inherited
@Target({ElementType .TYPE,ElementType. FIELD,ElementType .METHOD,ElementType. PARAMETER})
public @interface MyAnnotation {
}
还有一个只需要改了名字即可
然后,使用:
把原来的bind去掉,改成MyOtherAnnotation即可(随便)
ind(IFoo. class).annotatedWith(MyAnnotation .class).to(Foo. class);
bind(IFoo.class).annotatedWith( MyOtherAnnotation.class ).to(OtherFoo.class) ;
使用
@Inject @MyAnnotation
IFoo ifoo;
@Inject @MyOtherAnnotation
IFoo iFoo;
绑定Bindings 可以有下面几种类型:
- Linked bindings
- instance bindings
- @provider methods
- provider bindings
- constructor bindings
- untargetted bindings
- built-in bindings
- just-in-time bindings
- providers 等
1,Linked bindings允许链接,比如
现在有三个类,A,B,C,其中B继承或者实现A,C继承或者实现B
那么,在module中的configure中使用如下:
bind(A.class).to(B.class);
bind(B.class).to(C.class);
在使用的时候,@Inject A vir ;//得到的示例是C的实例
2,instance bindings
一般用于常见简单类型,比如String Integer,
定义(在configure中):
bind(Integer.class)
.annotatedWith(Names.named("width"))
.toInstance(100);
bind(Integer.class)
.annotatedWith(Names.named("height"))
.toInstance(120);
以后使用@Named("name")就可以获得他的值
bind(String. class).annotatedWith(Names.named ("Name" )).toInstance("liweijie") ;
bind(Integer.class)
.annotatedWith(Names.named ("age" ))
.toInstance(120 );
用途一般是在构造函数当中,例如
@Inject
Foo(@Named( "Name")String name) {
this .name = name ;
Log.i("TAG" , name + "=name" );
}
这样子是固定了条用@Injec Foo的时候,传入的参数是liweijie
在其他地方使用,可能为null
3,@Provider method
这个方法必须定义在模块中(Module),而且必须使用@Provides 标注,在个方法的返回类型则绑定到这个方法返回的对象实例。
比如:
@Provides @Named ("FooInstane")
Foo provider()
{
return new Foo("hello world") ;
}
使用
@Inject
@Named("FooInstane")
Foo fooInsatece;
这样子,就为fooInstance赋值。
4,provider bindings
当有一些比较复杂的数据的组合而成的对象的时候,我们通过接口和实现,然后通过
其中
bind(A.class).toProvider(B.class);
来实现。例如
public class MyProvider implements Provider<Foo> {
@Override
public Foo get() {
return new Foo("hello guangzhou") ;
}
}
然后绑定
bind (Foo.class ).toProvider(MyProvider.class) ;
最后使用
@Inject
Foo foo;
即可获得实例
5,untargetted bindings
Untargetted Bindings不含to语句。
比如;
bind(MyConcreteClass.class);
bind(AnotherConcreteClass.class).in(Singleton.class);
一般用于含有@ImplementedBy 和@ProvidedBy
但是,加入需要annotationWith(...)就需呀to,也就是taget,哪怕是本类,比如
bind(MyConcreteClass.class) .annotatedWith(Names.named("foo")) .to(MyConcreteClass.class);
bind(AnotherConcreteClass.class) .annotatedWith(Names.named("foo")) .to(AnotherConcreteClass.class) .in(Singleton.class);
6
“即时绑定(Just-in-time Bindings)
a,
@ImplementedBy
比如:
@ImplementedBy(PayPalCreditCardProcessor.class)
public interface CreditCardProcessor
{
ChargeResult charge(String amount, CreditCard creditCard) throws UnreachableException;
}
等价于:
bind(CreditCardProcessor.class)2 .to(PayPalCreditCardProcessor.class);
假如他
定义了从Interface到实现的依赖,一般不建议使用,当他们都存在的时候,优先使用bind的
b,@ProvidedBy
比如
@ProvidedBy(DatabaseTransactionLogProvider.class)
public interface TransactionLog
{
void logConnectException(UnreachableException e);
void logChargeResult(ChargeResult result);
}
等价于
bind(TransactionLog.class) .toProvider(DatabaseTransactionLogProvider.class);
都存在的时候有限使用bind。
7,使用Exter
就是用于Budnle之间传值
Intent di = new Intent();
di.setClass(context, InjectExtraReceiver.class) ;
di.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);
di.putExtra("Extra1","Message1");
di.putExtra("Extra2","Message2");
context.startActivity(di);
这些,我们都是按照原来之前的传递拼装就好,但是,到了被启动的Activity,可以使用如下找到他的值,其中options =true表示为可选,当没有这个值的时候是null
@InjectExtra ("Extra1" ) String extra1;
@InjectExtra ("Extra2" ) String extra2;
@InjectExtra (value="Extra3" , optional=true) String extra3;
9,Events
Roboguice 提供了对Context 生命周期相关的事件的send 和receive ,系统缺省支持的事件为:
* OnActivityResultEvent
* OnConfigurationChangedEvent
* OnContentChangedEvent
* OnContentViewAvailableEvent
* OnCreateEvent
* OnDestroyEvent
* OnNewIntentEvent
* OnPauseEvent
* OnRestartEvent
* OnResumeEvent
* OnStartEvent
* OnStopEvent
@observes 只能应用到方法上,而不能应用到构造函数上
常见错误:
11-18 08:04:09.068 2928-2928/retrofit.com.example.user.roboguicedemo E/AndroidRuntime: FATAL EXCEPTION: main
11-18 08:04:09.068 2928-2928/retrofit.com.example.user.roboguicedemo E/AndroidRuntime: java.lang.RuntimeException:
Unable to start activity ComponentInfo{retrofit.com.example.user.roboguicedemo/retrofit.com.example.user.roboguicedemo.MainActivity}:
com.google.inject.ConfigurationException: Guice configuration errors:
解决办法,应该是有些地方使用注解不合理,比如只有Named却把Inject也添加上了