依赖注入
使用
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); }
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.f2er.com/javaschema/283040.html