Dragger2学习笔记

Dragger2学习笔记

dragger2-android

使用这个的意义

使用Dagger2开发Android的话,有一个困难就是android的一些框架类,如Activity和Fragment等,他们的实例化由操作系统完成,如果要想让Dagger2也能很好地注入这些对象,你不得不在生命周期里添加以下代码完成注入过程。

public class FrombulationActivity extends Activity { @Inject Frombulator frombulator; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // DO THIS FIRST. Otherwise frombulator might be null! ((SomeApplicationBaseType) getContext().getApplicationContext()) .getApplicationComponent() .newActivityComponentBuilder() .activity(this) .build() .inject(this); // ... now you can write the exciting code } } 

这样做存在以下问题:

1.上面的代码要复制粘贴到所有的Activity中,这就会给以后重构代码造成麻烦,你的团队越来越多的人复制上面的代码块,会有越来越少的人知道这块代码的真正用途。 2.更重要的是,它要求请求注射类型(FrombulationActivity )知道它的注射器,既即使它可以通过接口而不是具体的类型完成,但是它打破了依赖注入的核心原则:一个类不应该知道任何关于它是如何注入的。 以上,所以基于Dagger2的,适用于Android开发的Dagger2-Android应运而生。

以上翻译以及以上的代码均来自Dagger2的官网, 官网传送门

 

而经过我自己的对比发现该库的以下好处

  1. 添加新的activity和presenter的时候,不需要修改Component,并声明自己的方法
  2. 不需要在每个activity手动注入,只需要在baseactivity中调用
AndroidInjection.inject(this);

就行了,子activity只需要通过泛型把需要加载的presenter类传递过去,就不必再考虑任何细节了

 

集成方法

  1. 首先确保工程已经集成了dragger2的依赖
  2. 在工程添加下面的依赖包
compile 'com.google.dagger:dagger-android:2.15'
compile 'com.google.dagger:dagger-android-support:2.15' // if you use the support libraries annotationProcessor 'com.google.dagger:dagger-android-processor:2.15' 
  1. 新建BaseActivity,最少应该具有以下代码
public abstract class BaseActivity<T extends AbstractPresenter> extends AppCompatActivity{ @Inject protected T mPresenter; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { AndroidInjection.inject(this); mPresenter.attachView(this); super.onCreate(savedInstanceState); } } 

4.新建BasePresenter,最少应该具有以下代码

public class BasePresenter<T extends BaseActivity> { protected T mView; public void attachView(T view) { this.mView = view; } } 

5.新建BaseActSubCompoent

@Subcomponent(modules = AndroidInjectionModule.class)
public interface BaseActSubComponent extends AndroidInjector<BaseActivity> { @Subcomponent.Builder abstract class Builder extends AndroidInjector.Builder<BaseActivity>{ } } 

6.新建AllActivityModule,以后所有需要注解的类,都需要在此注册,暂时此处只添加了MainActivity,以后如果需要添加其他的Activity,只需要照本宣科即可

@Module(subcomponents = BaseActSubComponent.class)
public abstract class AllActivityModule { @ContributesAndroidInjector(modules = MainActModule.class) abstract MainActivity contributeMainActivityInject(); } 

7.新建AppModule,用于Application的注入

@Module
public class AppModule { private final MyApplication application; public AppModule(MyApplication application) { this.application = application; } @Provides @Singleton MyApplication provideApplicationContext() { return application; } } 

8.新建Application的compoent,我这里叫AppComponent。

@Singleton
@Component(modules = {AndroidInjectionModule.class,
        AppModule.class,
        AllActivityModule.class})
public interface AppComponent {
  
    void inject(MyApplication application);

}

9.在自己的Application的oncreate中添加Dragger2的注入,同时,我们还需要让我们的Application实现HasActivityInjector接口。最后我们的Applicaion的代码如下

public class MyApplication extends Application  implements HasActivityInjector {
    @Inject
    DispatchingAndroidInjector<Activity> mAndroidInjector;
    private static MyApplication instance;

    @Override
    public void onCreate() {
        super.onCreate();
        DaggerAppComponent.builder()
                .appModule(new AppModule(instance))
                .build().inject(this);

        instance = this;

    }

    public static MyApplication getInstance() {
        return instance;
    }

    @Override
    public AndroidInjector<Activity> activityInjector() {
        return mAndroidInjector;
    }
}

10.经过上面的步骤,我们基本上已经搭建好最基本的框架了,现在只需要把我们要注入的activity添加进去就行了。假如我们要注入MainActivity。那么我们只需要让我们的Activity继承自BaseActivity即可。具体代码如下 MainActivity

public class MainActivity extends BaseActivity<MainPresenter> { @Override protected void onCreate(Bundle savedInstanceState) { // AndroidInjection.inject(this); super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } public void showMsg(String msg){ Toast.makeText(this,msg,Toast.LENGTH_SHORT).show(); } } 

同样我们的presenter也是这样操作

public class MainPresenter extends BasePresenter<MainActivity> { // @Inject public MainPresenter() { new Handler().postDelayed(new Runnable() { @Override public void run() { mView.showMsg("哈哈哈哈哈"); } },1500); } } 

11.最后我们再新建一个MainActModule

@Module()
public abstract class MainActModule { @Provides static MainPresenter provideStudent(){ return new MainPresenter(); } } 

同时把MainActModule在AllActivityModule中予以注册,由于我们在上面已经注册过了,所以就不再赘述了。

这样编译运行以后,就可以看到我们的presenter已经在Activity中注入成功。如果我们要注入新的activity只需要重复第10和11步即可

后续优化

  1. 上面的方法已经很简单了,但是你可能仍然觉得比较冗余。所以我们仍然可以优化其中的方法。我们可以在Presenter的构造函数上面,添加一个注解标识符@Inject。最终代码如下
public class MainPresenter extends BasePresenter<MainActivity> { @Inject public MainPresenter() { new Handler().postDelayed(new Runnable() { @Override public void run() { mView.showMsg("哈哈哈哈哈"); } },1500); } } 

添加了这个注解以后,我们就可以删除我们在MainActModule的方法。使MainActModule最终变成

@Module()
public abstract class MainActModule { } 

这样是不是变得更加方便注入了?

  1. 有人肯定会说,那假如我的presenter的构造函数是有参数的,那该怎么办。当然,我们也是有方法的。首先我们假设presenter的构造函数需要传递一个student对象过去,那么我们的presenter就变成了这样
public class MainPresenter extends BasePresenter<MainActivity> { @Inject public MainPresenter(final Student student) { new Handler().postDelayed(new Runnable() { @Override public void run() { mView.showMsg("哈哈哈哈哈"+student.toString()); } },1500); } } 

那么这里需要的student从哪里来呢?毕竟我们已经在MainActModule中删除了new Presenter的方法。这时候我们就需要改造AppComponent和AppModule了。我们需要在AppComponent中声明返回类型是Student的方法,并在AppModul中实现返回类型是Student的方法

最后AppComponent的代码

@Singleton
@Component(modules = {AndroidInjectionModule.class,
        AppModule.class,
        AllActivityModule.class})
public interface AppComponent {

    void inject(MyApplication application);

    MyApplication getContext(); Student getStudent(); } 

AppModul的代码

@Module
public class AppModule { private final MyApplication application; public AppModule(MyApplication application) { this.application = application; } @Provides @Singleton MyApplication provideApplicationContext() { return application; } @Provides @Singleton Student provideStudent() { return new Student(); } } 

这样完成了presenter的构造函数包含参数的注入

posted @ 2018-08-14 13:47 蓝冷然 阅读( ...) 评论( ...) 编辑 收藏
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值