如果對 Retrofit2+RxJava 封裝還不是很了解的話
可以參考下:
http://www.reibang.com/p/17e3e3102c1f
如果對Dagger2 還不是很了解,可以參考下:
http://www.reibang.com/p/cd2c1c9f68d4
如果對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直接在基類中注入.對其進行統(tǒng)一管理:
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進行統(tǒng)一處理.
/**
* 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的童鞋,可能會發(fā)現(xiàn)沒有DaggerAppComponent
這個類,不要慌,請'Make Project'編譯下項目.DaggerAppComponent
會自動生成.DaggerAppComponent
其實是根據(jù)我們寫的AppComponent
接口生成的一個類,下面我們先看下AppComponent.
@Singleton
@Component(modules = AppModule.class)
public interface AppComponent {
Context getContext();
ServerApi getServerApi();
}
AppComponent這個接口其實很簡單.這里記得要加上@Scope
注解(@Singleton是@Scope的一種)使Component和Module中provide出來的對象聯(lián)系起來.
關于@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只創(chuàng)建了一次,所以產(chǎn)生'單例'這個現(xiàn)象.(我這里又重復得說了一邊,汗~~)
AppComponent和AppModule請根據(jù)自己項目的詳細情況來進行封裝,由于我這個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需要
注入,如果不注入,在基類中調(diào)用mPresenter.attach會出錯.
當你使用Dagger2的時候,其實很明顯會暴露他的一個缺點,必須要編譯后,才能產(chǎn)生對應的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