guice/roboguice框架学习

框架介绍

roboguice是google公司的一款依赖注入框架,基于guice。可以减少findviewbyid的使用和new的使用。

使用方法

在android studio中使用

在gradle中使用如下语句可以引入roboguice.


 project.dependencies {
compile 'org.roboguice:roboguice:3.+'
provided 'org.roboguice:roboblender:3.+'
}

在activity中使用

activity必须继承RoboActivity。


public class MyActivity extends RoboActivity{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
}

绑定view
  1. 绑定contentview:@ContentView(R.layout.main)。
  2. 绑定view:@injectView(R.id.textview) TextView textview;
绑定资源

@InjectResource(R.anim.my_animation) Animation myAnimation;

绑定服务

 @Inject Vibrator vibrator;
@Inject NotificationManager notificationManager;

这里的服务不是android四大组件中的服务,而是指系统服务。系统服务是Android操作系统Java应用程序下层的,伴随操作系统启动而运行的系统后台服务程序(位于Android系统的FrameWork层)。

绑定pojo类

pojo类是简单的java bean类。

class Foo {
@Inject Bar bar;
}
class Foo{
Bar bar;
@inject Foo(Bar bar){
this.bar=bar;
}
}

单例模式
普通单例模式


@Singleton the whole app
class Foo {
}

这种单例在整个生命周期中有效,Foo类不会被垃圾回收器回收,除非整个应用结束。

Context中单例


@ContextSingleton context
class Foo {
}

在整个Context生命周期内为单例,当Context存活时,Foo类不会被垃圾回收器回收。

Fragment中单例


@FragmentSingleton
public class Bar {
}

在Fragment的整个生命周期中为单例,当fragment不被销毁时,Foo类不会被垃圾回收器回收。

绑定自己的类

类:


public interface IFoo {}
public class Foo implements IFoo {}

在activity中注入


public class MyActivity extends RoboActivity {
//How to tell RoboGuice to inject an instance of Foo ?
@Inject IFoo foo;
}

在AndroidManiFest.xml中注册



android:value="com.example.MyModule,com.example.MyModule2" />

创建module继承自AbstractModule


package com.example;

public class MyModule extends AbstractModule {
//a default constructor is fine for a Module

public void bind() {
    bind(IFoo.class).to(Foo.class);
}

}

public class MyModule2 extends AbstractModule {
//if your module requires a context, add a constructor that will be passed a context.
private Context context;

//with RoboGuice 3.0, the constructor for AbstractModule will use an `Application`, not a `Context`
public MyModule( Context context ) {
    this.context = context;
}

public void bind() {
    bind(IFoo.class).toInstance( new Foo(context));
}

}

绑定intentExtra数据


@ContentView(R.layout.activity_second)
public class SecondActivity extends RoboFragmentActivity {

@InjectExtra(value = "pull", optional = true)
String pull;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Gson gson = RoboGuice.getInjector(this).getInstance(Gson.class);
    String demoStr = gson.toJson(pull);
    Ln.d(demoStr);
}

}

在Fragment中使用

必须继承RoboFragment


public class MyFragment extends RoboFragment {
// Inject your view
@InjectView(R.id.text1) TextView nameTextView;

// Inflate your view as you normally would for any fragment...
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    return inflater.inflate(R.layout.my_layout, container, false);
}

}

在onViewCreated方法中使用注入的view。

在service中和broadcast receiver中使用

必须继承RoboService


public class MyService extends RoboService {

@Inject ComputeFooModule computeFooModule;

public void onCreate() {
super.onCreate();
//All injections are available from here :
computeFooModule.setUp();
}

public int onStartCommand(Intent intent, int flags, int startId) {
computeFooModule.computeFoo();
return super.onStartCommand();
}

}


public class MyBroadcastReceiver extends BroadcastReceiver {

@Inject ComputeFooModule computeFooModule;

protected void handleReceive(Context context, Intent intent) {
    //All injections are available from here :
    computeFooModule.setUp().computeFoo();
    ...

}

}

绑定自定义View


class MyView extends View {
@Inject Foo foo;
@InjectView(R.id.my_view) TextView myView;

public MyView(Context context) {
    inflate(context,R.layout.my_layout, this);
    RoboGuice.getInjector(getContext()).injectMembers(this);
    onFinishInflate();
}

public MyView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    inflate(context,R.layout.my_layout, this);
}

public MyView(Context context, AttributeSet attrs) {
super(context, attrs);
    inflate(context,R.layout.my_layout, this);
}

@Override
public void onFinishInflate() {
    super.onFinishInflate();
    //All injections are available from here
    //in both cases of XML and programmatic creations (see below)
    myView.setText(foo.computeFoo());
}

}

通过

RoboGuice.getInjector(getContext()).injectMembers(this);
来绑定view。

在ContentProvider中注入

在module中使用


@Provides
@Named("example_authority_uri")

注释来绑定。
通过

@Inject
@Named("example_authority_uri")

来使用。
比如:

public class ContentProvidersModule extends AbstractModule {
@Override
protected void configure() {
}

@Provides
@Named("example_authority_uri")
public Uri getExampleAuthorityUri() {
    return Uri.parse("content://com.example.data");
}

}



public class MyExampleContentProvider extends RoboContentProvider {

@Inject
@Named("example_authority_uri")
private Uri contentUri;

private UriMatcher uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);

@Override
public boolean onCreate() {
    super.onCreate();
    uriMatcher.addURI(contentUri.getAuthority(), "foo/#", 0);
    return true;
}

@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
    switch (uriMatcher.match(uri)) {
        case 0:
            // Return results of your query
            return null;
        default:
            throw new IllegalStateException("could not resolve URI: " + uri);
    }

    return null;
}

@Override
public String getType(Uri uri) {
    return null;
}

@Override
public Uri insert(Uri uri, ContentValues values) {
    return null;
}

@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
    return 0;
}

@Override
public int update(Uri uri, ContentValues contentValues, String selection, String[] selectionArgs) {
    return 0;
}

}

RoboGuice中的Event使用

RoboGuice中实现了自己的观察者模式,可以在Context中传递事件。(不能跨Actibity传递事件感觉比较鸡肋)
其中系统已经实现的事件有:

  • OnActivityResultEvent

  • OnConfigurationChangedEvent

  • OnContentChangedEvent

  • OnContentViewAvailableEvent

  • OnCreateEvent

  • OnDestroyEvent

  • OnNewIntentEvent

  • OnPauseEvent

  • OnRestartEvent

  • OnResumeEvent

  • OnStartEvent

  • OnStopEvent
    通过在activity中使用如下方法可以监听这些事件:


    public void doSomethingOnResume( @Observes OnResumeEvent onResume ) {
    Ln.d("Called doSomethingOnResume in onResume");
    }

    使用@Observes这个注释来观察这个事件。
    或者在activity中声明一个监听器来监听事件

    public class MyActivity extends RoboActivity {
    // You must "register" your listener in the current context by injecting it.
    // Injection is commonly done here in the activity, but can also be done anywhere really.
    @Inject protected MyListener myListener;

    }

    class MyListener {

      // Any method with void return type and a single parameter with @Observes annotation
      // can be used as an event listener.  This one listens to onResume.    
      public void doSomethingOnResume( @Observes OnResumeEvent onResume ) {
          Ln.d("Called doSomethingOnResume in onResume");
      }
    

    }

自定义事件


public class MyOtherActivity extends RoboActivity {
// You'll need the EventManager if you want to trigger an event.
@Inject protected EventManager eventManager;

    @InjectView(R.id.buy_button) protected Button buyButton;

    protected void onCreate( Bundle savedInstanceState ) {
        super.onCreate(savedInstanceState);

        buyButton.setOnClickListener( new OnClickListener() {
            public void onClick() {
                // trigger the event
                eventManager.fire(new MyBuyEvent() );
            }
        })
    }

    // handle the buy event
    protected void handleBuy( @Observes MyBuyEvent buyEvent ) {
        Toast.makeToast(this, "You won't regret it!", Toast.LENGTH_LONG).show();
    }
}

// The event class can be anything you want
class MyBuyEvent {
    ...
}

总结

RoboGuice作为一款依赖注入框架可以提供多种注入,比如视图、pojo类、自定义类等。大量减少了findviewbyid和new的编写。
当一个类依赖于另一个类时,需要在类中创建一个类的实例。当使用了依赖注入后,所依赖的类的创建不在类中,而是在外部创建然后注入到类里面。

与ButterKnife和xutils3的区别
缺点
  • ButterKnife和xutils3的注入支持绑定事件和在Adapter中使用,但是RoboGuice不可以,这是RoboGuice最大的缺点。
  • Event只能在同一个Context中传递,感觉略鸡肋。
优点
  • RoboGuice可以注入资源、动画和系统服务等,减少了代码量使代码更加简洁。
  • 依赖类的初始化不用在类中完成,解耦。
  • 可以通过@single、@contextsingle、@fragmentsingle来确定作用域。
  • @provide提供了强大的绑定类型能力。
  • 可以绑定IntentExtra中的数据

你可能感兴趣的:(guice/roboguice框架学习)