Android开发使用RoboGuice3.0框架进行注入

原创 2015年11月18日 23:23:55
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也添加上了

























版权声明:本文为博主原创文章,未经博主允许不得转载。

Android常见的依赖注入框架简单使用

三个常见依赖注入框架配置简单介绍。
  • u012149927
  • u012149927
  • 2016年08月14日 23:31
  • 1018

View注入框架:Butterknife简单使用

我在网上找Butterknife的时候,发现很少,就去官网研究了一下,就写了Butterknife详解与大家分享,如果有什么问题,欢迎大家向我提出。...
  • kun5069073
  • kun5069073
  • 2015年08月18日 11:06
  • 1919

Android 依赖注入:Dagger 实例讲解(Demo下载)

Dagger 是一种android平台的依赖注入框架,是有一家专注于移动支付的公司,Square公司推出的库,这家公司也推出了 其他在Android开发中常用库:otto,okhttp,retrofi...
  • zjbpku
  • zjbpku
  • 2014年01月24日 23:50
  • 26332

Android注入框架你应该知道的一切------打造自己的注入框架

http://blog.csdn.net/codebob/article/details/46434537 前言 Java的所有框架基本都是基于反射的,所以有句话是这么说的,无反射,无框架。所以An...
  • Baple
  • Baple
  • 2015年06月10日 08:25
  • 1532

一个Android事件注入框架详解

Github上有很多关于事件注入的框架,大致上原理都差不多,但很少详细介绍整个框架的各个组成部分以及实现原理,本文以作者wyouflf@gmail.com的xUtils为例详细介绍整个框架的实现。 ...
  • HCadillac
  • HCadillac
  • 2015年09月23日 10:51
  • 223

Android快速依赖注入框架Dagger2使用1

一、啥是Dagger2前面的概念可能开始看不懂,给点耐心,看到例子就懂了。 本篇文章需要注解方面的知识,不了解的可以先看:http://blog.csdn.net/niubitianping/arti...
  • niubitianping
  • niubitianping
  • 2017年03月08日 18:22
  • 2340

Android之---ButterKnife-View注入框架(简单介绍和在Studio中安装)

ButterKnife-View注入框架(简单介绍和在Studio中安装)
  • u010936731
  • u010936731
  • 2016年12月07日 10:53
  • 679

android注入之ButterKnife的使用

注入的话相信大家应该都是很熟悉的,他不仅把代码的结构简洁化,还能减少很大一部分的findviewByid的代码量 ,但是平时看到的注入都是封装在一个大的框架中的,比如xUtils,这里我们来介绍下一个...
  • u013424496
  • u013424496
  • 2016年04月22日 09:52
  • 1495

Android注入框架你应该知道的一切------打造自己的注入框架

前言Java的所有框架基本都是基于反射的,所以有句话是这么说的,无反射,无框架。所以Android的注入框架也是基于反射的,接下来就简单的介绍一下Android的注入框架你应该知道的一切。注解简介注解...
  • shengbo1992
  • shengbo1992
  • 2015年06月10日 00:40
  • 2353

android studio 配置androidannotations注入框架,问题一二三

最近比较闲,老是感觉编码应该是项轻松的感觉,代码不应该繁复!好的代码应该是易于理解,易读的,但是鉴于在同一个团队中各个人的水平不一样,然后代码风格也不一样,导致每次改代码修BUG的时候就莫名的烦躁,然...
  • diguoweiwu
  • diguoweiwu
  • 2016年03月09日 18:22
  • 367
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Android开发使用RoboGuice3.0框架进行注入
举报原因:
原因补充:

(最多只允许输入30个字)