如果对Dagger2 还不是很了解,可以参考下:
如果对mvp还不是很了解,可以自己百度下,很多的,我就不贴出了.
下面我简单讲述下:
请先看下目录结构:
com └── javalong └── rrdm ├── activity │ ├── component │ │ ├── LoginActivityComponent.java │ │ └── MainActivityComponent.java │ ├── iview │ │ ├── ILoginView.java │ │ └── IMainView.java │ ├── LoginActivity.java │ ├── MainActivity.java │ ├── module │ │ ├── LoginActivityModule.java │ │ └── MainActivityModule.java │ └── presenter │ ├── LoginPresenter.java │ └── MainPresenter.java ├── app │ ├── annotation │ │ └── ActivityScope.java │ ├── AppBaseActivity.java │ ├── AppBaseApplication.java │ ├── component │ │ └── AppComponent.java │ ├── iview │ │ └── MvpView.java │ ├── module │ │ └── AppModule.java │ └── presenter │ └── AppPresenter.java └── retrofit ├── ResponseMessageBean.java ├── RetrofitHelper.java ├── ServerApi.java ├── TWGsonConverterFactory.java ├── TWGsonRequestBodyConverter.java ├── TWGsonResponseBodyConverter.java └── TWJavaCallAdapterFactory.java
这里我就不对mvp,dagger2和Retrofit2+Rxjava过多介绍了.这里就介绍下具体的封装.
我这里是一个Presenter和一个Activity(View)相互对应,所以我让Presenter直接在基类中注入.对其进行统一管理:
AppPresenter.java:
/** * Created by javalong on 16-12-27. * presenter基类 */ public abstract class AppPresenter<V extends MvpView>{ @Inject protected V mvpView; public AppPresenter(V mvpView) { this.mvpView = mvpView; } public abstract void attach(); public abstract void detach(); }
AppBaseActivity.java--->所有Activity的基类,对presenter进行统一处理.
/** * Created by javalong on 16-12-27. */ public abstract class AppBaseActivity<T extends AppPresenter> extends AppCompatActivity { @Inject protected T mPresenter; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); initInjects(); mPresenter.attach(); } protected abstract void initInjects(); @Override protected void onDestroy() { super.onDestroy(); mPresenter.detach(); } protected AppComponent getAppComponent(){ return AppBaseApplication.getInstance().getAppComponent(); } }
AppBaseActivity中引用了AppComponent.这个需要在AppBaseApplication进行初始化.Component是dagger2依赖注入的基础.
AppBaseApplication.java
/** * Created by javalong on 16-12-27. */ public class AppBaseApplication extends Application { private static AppBaseApplication instance; public static AppBaseApplication getInstance() { return instance; } AppComponent appComponent; public AppComponent getAppComponent() { return appComponent; } @Override public void onCreate() { super.onCreate(); instance = this; if (appComponent == null) { appComponent = DaggerAppComponent.builder().appModule(new AppModule(this)).build(); } } }
如果不熟悉Dagger2的童鞋,可能会发现没有`DaggerAppComponent`这个类,不要慌,请'Make Project'编译下项目.`DaggerAppComponent`会自动生成.
`DaggerAppComponent`其实是根据我们写的`AppComponent`接口生成的一个类,下面我们先看下AppComponent.
@Singleton @Component(modules = AppModule.class) public interface AppComponent { Context getContext(); ServerApi getServerApi(); }
AppComponent这个接口其实很简单.这里记得要加上`@Scope`注解(@Singleton是@Scope的一种)使Component和Module中provide出来的对象联系起来.
关于@Scope注解的含义我这里就不过多介绍了,大家可以参考我上面推荐的文章.写的很不错.
接下来看下AppModule中提供了哪些依赖
@Module public class AppModule { private Context mContext; public AppModule(Context context) { this.mContext = context; } @Provides @Singleton Context provideContext(){ return mContext; } @Provides @Singleton ServerApi provideServerApi(Context context){ RetrofitHelper.init(context); return RetrofitHelper.getApi(); } }
这里的@Singleton 和前面AppComponent的@Singleton 相互连接,让我们造成了单例的假象.其实@Singleton并没有单例的作用,是因为
和AppComponent一起使用,AppComponent只创建了一次,所以产生'单例'这个现象.(我这里又重复得说了一边,汗~~)
AppComponent和AppModule请根据自己项目的详细情况来进行封装,由于我这个demo比较简单,所以只@Provides 了2个对象出来.
下面我来详细介绍下Activity和Presenter之间的封装.
首先我这里先说明下,我这里的一个Activity,对应着1个view,1个presenter,1个component,1个module.
可能封装的不是很好,没有领悟到mvp的精髓,但是对我来说更加清晰.
MainActivity.java
public class MainActivity extends AppBaseActivity<MainPresenter> implements IMainView{ @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mPresenter.test(); } @Override protected void initInjects() { DaggerMainActivityComponent.builder() .appComponent(getAppComponent()) .mainActivityModule(new MainActivityModule(this)) .build() .inject(this); } @Override public void showMainMessage() { ((TextView)findViewById(R.id.tv_test)) .setText("你好 dagger"); findViewById(R.id.bt_login) .setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { LoginActivity.start(MainActivity.this); MainActivity.this.finish(); } }); } }
MainActivity必须继承AppBaseActivity,然后传入泛型,即对应的Presenter的类型.在initInjects中必须完成Dagger2的注入操作,因为在AppBaseActivity中的Presenter需要
注入,如果不注入,在基类中调用mPresenter.attach会出错.
当你使用Dagger2的时候,其实很明显会暴露他的一个缺点,必须要编译后,才能产生对应的Dagger**Component.当然相对于他的好处来讲,这点还是可以忍受的.
前面提到了必须要对基类中的Presenter进行注入,那么到底注入的是什么呢?这里我以MainPresenter为例.
public class MainPresenter extends AppPresenter<IMainView>{ @Inject public MainPresenter(IMainView mvpView) { super(mvpView); } @Override public void attach() { } @Override public void detach() { } public void test() { mvpView.showMainMessage(); } }
MainActivityModule.java
@Module public class MainActivityModule { private IMainView mainView; public MainActivityModule(IMainView mainView) { this.mainView = mainView; } @Provides @ActivityScope IMainView provideIMainView(){ return mainView; } /** * 这种方式,和直接在MainPresenter构造方法上添加@Inject是一样的 * 二选一即可. */ // @Provides @ActivityScope MainPresenter provideMainPresenter(IMainView mainView){ // return new MainPresenter(mainView); // } }
看注释,这里有2种方式可以完成MainPresenter的注入,一种是直接在MainPreenter的构造方法上加上@Inject,一种是在对应的Module中使用
@Provides 把MainPresenter提供出来. 至于@ActivityScope其实是和前面@Scope一样的,我这里就不过多介绍了.
最关键的一步:
MainActivityComponent.java
@ActivityScope @Component(dependencies = AppComponent.class,modules = MainActivityModule.class) public interface MainActivityComponent{ /** * @param mainView * 这里必须使用MainActivity,不能使用IMain接口 * 否则会造成@Inject注入失败 */ void inject(MainActivity mainView); }
必须在对应的Component提供注入方法(名字不一定叫inject).
MainActivity.java 部分代码
@Override protected void initInjects() { DaggerMainActivityComponent.builder() .appComponent(getAppComponent()) .mainActivityModule(new MainActivityModule(this)) .build() .inject(this); }
这样才完成了注入.
在`DaggerMainActivityComponent`中会先对AppBaseActivity进行注入,然后再对MainActivity进行注入.
这里我简单的讲述了封装,如果还有什么不懂的地方可以再交流~~~
github: https://github.com/javalong/Retrofit2-RxJava-Dagger2-MVP
共同学习,写下你的评论
评论加载中...
作者其他优质文章