依赖注入
使用
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是有冲突的,