依赖注入框架解析

依赖注入

使用

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是有冲突的,

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值