依赖注入框架解析

xiaoxiao2021-02-28  65

依赖注入

使用

ButterKnife 在setContentView(..);之后加入ButterKnife.bind(this), @BindView(R.id.testFre)SimpleDraweeView testFre; @BindView(R.id.test)TextView test;

Dagger2:

场景:想在一个类中使用新建另外一个类,但是又觉得显示创建耦合性太高,所以使用Dagger。其实Dagger的使用是比较简单的,主要在需要新建一个类和一个接口:

1、新建Module类:

@Module public class DemoModule { @Provides Person providePerson(){//声明需要依赖注入的类,方法名可以是任意的 return new Person(); } }

2、新建Component接口:

@Component(modules=DemoModule.class) public interface DemoComponent { void inject(Dagger2Activity activity);//设置需要在那个类里进行依赖注入,也就是声明宿主 Person getPerson();//这是依赖注入的第二种方法,一般用在全局设置中,如框架整合 }

3、两种形式的使用,请注意区别:

第一种实现 public class Dagger2Activity extends AppCompatActivity { @Inject Person person;//使用@Inject在宿主Dagger2Activity中依赖注入Person, @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_dagger2); //特别注意DaggerCarComponent是Dagger2自动生成的,需要reBuild或者Make Project生成 DemoComponent component = DaggerDemoComponent.builder().build(); //进行注入 component.inject(this); Log.i("111",person.toString()); } } 第二种实现 public class Dagger2Activity extends AppCompatActivity { Person person;//第二种实现 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_dagger2); //特别注意DaggerCarComponent是Dagger2自动生成的,需要reBuild或者Make Project生成 DemoComponent component = DaggerDemoComponent.builder().build(); //进行注入 component.inject(this); person=component.getPerson(); Log.i("111",person.toString()); } }

需要注意的是Dagger2主要进行模块间的解耦,这里是最简单的使用demo。一般来说会配合MVP设计模式,以及一些其他的网络或者图片框架(Retrofit,RxAndroid,glide,Gson)使用,这些整合并不冲突。

MVP+Dagger2:这里假设已经已经搭好了简单的MVP架构。

1、新建一个Module类和Component接口

@Module public class UserModule { private final IUserView view ; public UserModule(IUserView view){ this.view = view ; } @Provides IUserView provideILogView(){ return view;//注意这里选择使用IUserView作为依赖注入对象 } } @Component(modules = UserModule.class) public interface UserComponent { public void inject(MvpActivity activity); }

2、修改Presenter中的代码:

public class UserPresenter { private IUserView mUserView; private IUserModel mUserModel; //修改前代码 public UserPresenter(IUserView view) { mUserView = view; mUserModel = new UserModelImpl(); } //修改后代码 @Inject public UserPresenter(IUserView view) { mUserView = view; mUserModel = new UserModelImpl(); Log.i("xixi","依赖注入了presenter"); } public void saveUser( int id, String name) { mUserModel.getID(); } public void loadUser( int id) { UserBean user = mUserModel.load(id); mUserView.setName(user.getName()); // 通过调用IUserView的方法来更新显示 } }

3、修改宿主类:

@Inject UserPresenter mUserPresenter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_mvp); //mUserPresenter = new UserPresenter( this); DaggerUserComponent.builder().userModule(new UserModule(this)).build().inject(this); }

完成完成

MVP+Dagger2+Retrofit+RxAndroid+glide+Gson:

在MVp+Dagger2的基础上,可以进一步的将一些框架封装进来。大体思路如下:

1、将这些框架封装成一个完整的只暴露接口的类;

2、将这些类进一步封装到module中:

@Module public class RetrofitModule { @Provides public OkHttpClient provideOkHttpClient() { OkHttpClient okHttpClient = new OkHttpClient(); //okHttpClient.setConnectTimeout(60 * 1000, TimeUnit.MILLISECONDS); //okHttpClient.setReadTimeout(60 * 1000, TimeUnit.MILLISECONDS); return okHttpClient; } @Provides public Retrofit provideRetrofit(Application application, OkHttpClient okHttpClient){ Retrofit retrofit = new Retrofit.Builder() .baseUrl("") .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) // 添加Rx适配器 .addConverterFactory(GsonConverterFactory.create()) // 添加Gson转换器 .client(okHttpClient) .build(); return retrofit; } @Provides protected HttpService provideGitHubService(Retrofit retrofit) { return retrofit.create(HttpService.class); } }

HttpService代码如下:

public interface HttpService { @POST("test/{id}") Observable<UserBean> getData(@Path("id") int id); }

3、将这些module都封装到一个全局的AppComponent类中。

@Singleton @Component(modules = {RetrofitModule.class, GlideServiceModule.class}) public interface AppComponent { HttpService getService(); GlideService getImageLoader(); }

4、使用

Bufferknife

视图类以及资源的注入。 利用反射和注解。

@NonNull @UiThread public static Unbinder bind(@NonNull Activity target) { View sourceView = target.getWindow().getDecorView(); return createBinding(target, sourceView); }

其中sourceView是顶级装饰view,进一步追踪createBinding(target, sourceView)

private static Unbinder createBinding(@NonNull Object target, @NonNull View source) { Class<?> targetClass = target.getClass(); if (debug) Log.d(TAG, "Looking up binding for " + targetClass.getName()); //核心方法1,返回一个Constructor Constructor<? extends Unbinder> constructor = findBindingConstructorForClass(targetClass); if (constructor == null) { return Unbinder.EMPTY; } //noinspection TryWithIdenticalCatches Resolves to API 19+ only type. try { //核心方法2 return constructor.newInstance(target, source); } catch (IllegalAccessException e) { throw new RuntimeException("Unable to invoke " + constructor, e); } catch (InstantiationException e) { throw new RuntimeException("Unable to invoke " + constructor, e); } catch (InvocationTargetException e) { Throwable cause = e.getCause(); if (cause instanceof RuntimeException) { throw (RuntimeException) cause; } if (cause instanceof Error) { throw (Error) cause; } throw new RuntimeException("Unable to create binding instance.", cause); } }

Dagger2

@Inject

@Module

@Provides

@Component(modules = HttpHelperModule.class)

未完待续。

注意

ButterKnife和Dagger2是有冲突的,

转载请注明原文地址: https://www.6miu.com/read-64902.html

最新回复(0)