前言
我们都知道程序越写越大,耦合性就会越来越高,dagger2这个框架好处就在于解耦,其实他就类似与工厂模式。试想一种情况,当你当前类中依赖的对象是通过构造方法实现的,当起依赖对象所需要的参数发生改变时,你就要跟着改参数,着实很麻烦。好了,补多少下面我们就跟着一个简单的小例子来熟悉Dagger的简单使用。
首先添加依赖
implementation 'com.google.dagger:dagger:2.11'
annotationProcessor 'com.google.dagger:dagger-compiler:2.11'
在使用之前我们还是先来讲讲与使用有关的一点知识,不喜欢的或者说错的地方,尽管开喷。
Component
Component实际上就是一个注射器,简而言之,他会将你需要的对象注入到Activity或者Fragment中。
那么他所提供的依赖对象从哪里来了,好了下面我们就要讲Module了。
Module
他为Compnent提供依赖对象,我们一般将提供依赖对象的方法前加上Provides
最后使用
最后我们直接在程序需要对象的时候,inject就可以了。
提供一下注解的简单介绍:
首先我们一般在使用Dagger的时候,都会有一个Application,用于提供一些基础东西:
public class MyApp extends Application {
public static MyApp getMyApp() {
return myApp;
}
private static MyApp myApp;
public AppComponent getAppComponent() {
return appComponent;
}
private AppComponent appComponent;
private List<String>data=new ArrayList<>();
@Override
public void onCreate() {
super.onCreate();
myApp =this;//没有设置sesetter方法,所以要在生命周期刚开始时对其进行初始化
appComponent= DaggerAppComponent.builder()
.appModule(new AppModule(this,data))
.build();
}
}
然后分别看看AppComponent和AppModule
AppComponent:
@Singleton
@Component(modules = {AppModule.class})
public interface AppComponent {
//依赖当前AppComponent的Component会得到Context实例。在这里就是MainComponent。
Context getContext();
List<String> getDatas();
}
说明:这里可以看到AppComponent使用了单例模式,简而言之其中的对象都会被初始化一次。
这里暴露了两个方法,一个提供Context,一个提供List<String>类型的数据,这个时候你就可能会想到为什么要暴露这两个方法呢,其实接着往下看你就会明白,我们是想让这个AppComponent成一个基Component供其他的Component依赖。依赖的Conponent会获得上面的这两个实例。
AppMoudle:
@Module
public class AppModule {
Application application;
List<String> data;
public AppModule(Application application,List<String>data){
this.application=application;
this.data=data;
}
/**
* 提供Context
* @return
*/
@Provides
@Singleton
Context provideContext(){
return application;
}
/**
* 提供data
*/
@Provides
@Singleton
List<String> provideData(){
return data;
}
}
AppMoudle很简单提供Context和泛型数据集合,我们用到了@Provide注解。
然后看看MainComponent
@ActivityScope
@Component(dependencies={AppComponent.class},modules = {MainModule.class})
public interface MainComponent {
void inject(MainActivity mainActivity);
}
说明:我们这里用到了自定义注解@ActivityScope,因为这里依赖了AppComponent所以相当于划分了一个层级。可以看到这里面我们想把需要的对象注入到MainActivity中去。
MainMoudle
@Module
public class MainModule {
// @Singleton
@Provides
SharedPreferences provideSharedPrences(Context context){
return PreferenceManager.getDefaultSharedPreferences(context);
}
//@Singleton
@Provides
GenerateAdapter provideGenerateAdapter(Context mContext,List<String>data){
return new GenerateAdapter(mContext,data);
}
@Provides
TextView provideTextView(Context context){
return new TextView(context);
}
}
说明:这里我们简单提供三个需要注入的对象,分别是SharedPreferences,自定义Adapter GenerateAdapter和一个TextView
可能大家会想,为什么没有初始化Context和List<String>data,这是因为我们在MyApp里面已经初始话了,并且由AppMoudle提供Context和List<String>data.这两个实例是可以被MainMoudle拿来使用的,因为MainComponent依赖了AppComponnet。
好接下来看MainActivity.java
public class MainActivity extends AppCompatActivity {
@Inject
SharedPreferences sharedPreferences;
@Inject
GenerateAdapter generateAdapter;
@Inject
TextView textView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
DaggerMainComponent.builder()
.appComponent(MyApp.getMyApp().getAppComponent())
.mainModule(new MainModule())
.build()
.inject(this);
textView.setText("Serrywang");
Log.d("onCreate()",generateAdapter+","+sharedPreferences+","+textView.getText().toString());
}
}
接下来看输出结果:
D/onCreate(): com.example.wydnn.daggerdemo.MyAdapter.GenerateAdapter@bd7bfa3,android.app.SharedPreferencesImpl@25272a0,Serrywang
很明显我们注入成功了。
网友评论