依赖注入框架解析

前端之家收集整理的这篇文章主要介绍了依赖注入框架解析前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

依赖注入

使用

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.f2er.com/javaschema/283040.html

猜你在找的设计模式相关文章