dagger2使用详解

依赖注入,完美解决了类间解藕的问题。搞了接近一周的dagger,终于明白点了。将心得记录下来,庆祝一下。dagger与java的spring不同之处在于,dagger是采用了预编译技术而spring则是采用了反射技术。dagger对资源的消耗比spring小很多。知道了这点,使用起来就放心多了。

首先引入依赖库,

在app的gradle中添加

apply plugin: 'com.neenbedankt.android-apt'//不加这个,编译不过去


compile 'com.google.dagger:dagger:2.0.1'
apt 'com.google.dagger:dagger-compiler:2.0.1'//编译,自动生成代码用
provided 'org.glassfish:javax.annotation:10.0-b28'
compile 'com.jakewharton:butterknife:6.1.0'//

在项目的gradle中,添加

dependencies {
    classpath 'com.neenbedankt.gradle.plugins:android-apt:1.4'
}

这样之后,依赖包导入完成,可以愉快的写代码了

首先,介绍一下Dagger的必要组件,Module(用于提供各种需要的实例,这些实例会注入到dagger框架之中,供我们调用),Component(一个接口,会被dagger自动生成实现类,该实现类用于对注入的实例进行初始化操作)

然后看一下我们的需求,demo中的需求非常简单,在MainActivity中自动注入一个MainActivityPresenter,当点击MainActivity中的某一个Button时,调用MainActivityPresenter中的方法,弹出一个toast完事。看上去,需求很简单,但麻雀虽小,五脏俱全。

为了接近实际应用效果,我们让MainActivity模块依赖于一个全局模块。在实际应用中,这个需求很常见,dagger这样一个牛*的框架,当然也会想到了。为此,我们设计了这样两个模块。

Application模块。

组件包括AppModule(提供Application的实例),AppComponent,DaggerAppComponent在Application中初始化各实例。

看一下AppModule的代码:

@Module
public class AppModule {

    private Application application;

    public AppModule(Application application){
        this.application = application;
    }

    @Provides
    @Singleton
    public Application provideApplication(){
        return application;
    }

}

@Module  标记这个calss是一个Module,对外提供实例用
@Provides 标记方法返回值需要注入到dagger中

接下来看一下AppComponent的代码

@Singleton
@Component(modules = AppModule.class)
public interface AppComponent {

    Application getAppLication();


}

仅提供一个方法获取Application,自动生成的代码中这个application取自于AppModule

@Component(modules = AppModule.class)

这样,rebuild一下之后,我们就可以在Application中将需要的类初始化出来,看初始化代码

public class MyTestApplication extends Application {

    private AppComponent appComponent;


    public static MyTestApplication get(Context context){
        return (MyTestApplication)context.getApplicationContext();
    }

    @Override
    public void onCreate() {
        super.onCreate();

        appComponent = DaggerAppComponent.builder()
                .appModule(new AppModule(this))//初始化AppModule
                .build();

    }

    public AppComponent getAppComponent(){
        return appComponent;
    }
}

这样,application模块就算搞定了,这里的application主要是提供一个Application,还可以AppComponent中提供一些其他的工具类什么的,为了不影响主逻辑,这里就不写了。

最后,就可以写我们自己的业务逻辑了。

MainActivity模块,组件包括:MainActivityModule,MainActivityComponent,MainActivityPresenter。

看一下MainActivityModule的代码实现

@Module
public class MainActivityModule {

    private MainActivity mainActivity;

    public MainActivityModule(MainActivity mainActivity){
        this.mainActivity = mainActivity;
    }

    @Provides
    MainActivity provideMainActivity(){
        return mainActivity;
    }

    @Provides
    MainActivityPresenter providrMainActivityPresenter(){
        return new MainActivityPresenter(mainActivity);
    }

}

MainActivityComponent的代码是这个样子的


@ActivityScope//该注解表示MainActivityComponent的生命周期与调用他的Activity一样

@Component(modules = MainActivityModule.class,
        dependencies = AppComponent.class
)
public interface MainActivityComponent {


    MainActivity inject(MainActivity mainActivity);

    MainActivityPresenter presenter();


}

MainActivityPresenter的代码实现

public class MainActivityPresenter {

    private MainActivity mainActivity;

    public MainActivityPresenter(MainActivity mainActivity) {
        this.mainActivity = mainActivity;
    }

    public void systemTest() {

        Toast.makeText(mainActivity, "hhhhhh", Toast.LENGTH_LONG).show();
        Log.v("vhawk", "fucking great !");

    }

}

一切准备就绪了,那么牛*的MainActivity出场了

public class MainActivity extends AppCompatActivity {

    @Inject
    MainActivityPresenter presenter;//自动实例话

    @InjectView(R.id.hello)
    Button helloView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
            }
        });

        ButterKnife.inject(this);//点击事件注入

	/**
	  *初始化
	  */
        DaggerMainActivityComponent.builder()
                .appComponent(MyTestApplication.get(this).getAppComponent())
                .mainActivityModule(new MainActivityModule(this))
                .build().inject(this);

    }

    @OnClick(R.id.hello)
    public void test(){
        presenter.systemTest();
    }
}

Button点击的时候,神奇的现象发生了,正如你所期待的那样,打出了log,弹出了toast。















©️2020 CSDN 皮肤主题: 大白 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值