闲话不多说,直接上菜。。。
整个project的结构由data module和app module组成:
/*dagger2*/
compile 'com.google.dagger:dagger:2.4'
apt 'com.google.dagger:dagger-compiler:2.4'
//java注解
compile 'org.glassfish:javax.annotation:10.0-b28'
/*rxjava*/
compile 'io.reactivex:rxjava:1.1.0'
compile 'io.reactivex:rxandroid:1.1.0'
/*retrofit*/
compile "com.squareup.retrofit2:retrofit:2.0.2"
compile "com.squareup.retrofit2:converter-gson:2.0.2"
compile "com.squareup.retrofit2:adapter-rxjava:2.0.2"
/*Okhttp*/
compile 'com.squareup.okhttp3:okhttp:3.2.0'
compile 'com.squareup.okhttp3:logging-interceptor:3.2.0'
/*okhttp拦截器*/
compile "com.facebook.stetho:stetho:1.3.1"
compile "com.facebook.stetho:stetho-okhttp3:1.3.1"
/*butterknife*/
compile "com.jakewharton:butterknife:8.8.1"
apt "com.jakewharton:butterknife-compiler:8.8.1"
/*dagger2*/
compile 'com.google.dagger:dagger:2.4'
apt 'com.google.dagger:dagger-compiler:2.4'
//java注解
compile 'org.glassfish:javax.annotation:10.0-b28'
public interface ApiService {
@GET("news/latest")
Observable requestMainData();
}
public class Repository {
private ApiService mApiService;
public Repository(ApiService apiService) {
mApiService = apiService;
}
public Observable requestMainData() {
return mApiService.requestMainData();
}
}
@Module
public class DataModule {
/**host*/
private static final String BASE_UEL = "http://news-at.zhihu.com/api/4/";
/**
* 提供单例网络请求仓库
* @param apiService
* @return
*/
@Singleton
@Provides
public Repository provideRepository(ApiService apiService) {
return new Repository(apiService);
}
/**
* 提供单例Api
* @param retrofit
* @return
*/
@Singleton
@Provides
public ApiService provideApi(Retrofit retrofit) {
return retrofit.create(ApiService.class);
}
/**
* 提供单例RetrofitClient
* @param client
* @param factory
* @return
*/
@Singleton
@Provides
public Retrofit provideRetrofit(OkHttpClient client, Converter.Factory factory) {
return new Retrofit.Builder()
.baseUrl(BASE_UEL)
.client(client)
.addConverterFactory(factory)
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build();
}
/**
* 提供单例转换器
* @param gson
* @return
*/
@Singleton
@Provides
public Converter.Factory provideConverter(Gson gson) {
return GsonConverterFactory
.create(gson);
}
/**
* 提供单例Gson
* @return
*/
@Singleton
@Provides
public Gson provideGson() {
return new GsonBuilder()
.serializeNulls()
.create();
}
/**
* 提供单例OkHttpClient
* @param interceptor
* @return
*/
@Singleton
@Provides
public OkHttpClient provideClient(HttpLoggingInterceptor interceptor) {
return new OkHttpClient.Builder()
.addInterceptor(interceptor)
.addNetworkInterceptor(new StethoInterceptor())
.build();
}
/**
* 提供单例日志拦截器
* @return
*/
@Singleton
@Provides
public HttpLoggingInterceptor provideInterceptor() {
return new HttpLoggingInterceptor()
.setLevel(HttpLoggingInterceptor.Level.NONE);
}
}
public class DataManager {
@Inject
public Repository mRepository;
public DataManager() {
DaggerDataComponent.builder().dataModule(new DataModule()).build().injectDataManager(this);
}
}
@Singleton
@Component(modules = DataModule.class)
public interface DataComponent {
void injectDataManager(DataManager dataManager);
}
@Module
public class AppModule {
private Application mApplication;
public AppModule(Application application) {
mApplication = application;
}
/**
* 提供单例Application
* @return
*/
@Singleton
@Provides
public Application provideApplication() {
return mApplication;
}
/**
* 提供单例DataManager
* @return
*/
@Singleton
@Provides
public DataManager provideDataManager() {
return new DataManager();
}
}
@Singleton
@Component(modules = AppModule.class)
public interface AppComponent {
void injectApp(App app);
Application getApplication();
DataManager getDataManeger();
}
public class App extends Application {
private AppComponent mAppComponent;
private static App mApp;
@Override
public void onCreate() {
super.onCreate();
mApp = this;
mAppComponent = DaggerAppComponent.builder().appModule(new AppModule(this)).build();
mAppComponent.injectApp(this);
if (BuildConfig.DEBUG) {
Stetho.initialize(Stetho.newInitializerBuilder(this)
.enableDumpapp(Stetho.defaultDumperPluginsProvider(this))
.enableWebKitInspector(Stetho.defaultInspectorModulesProvider(this))
.build());
}
}
public AppComponent getAppComponent() {
return mAppComponent;
}
public static App getInstance() {
return mApp;
}
}
public interface BaseModel {
}
public interface BaseView {
}
public interface BasePresenter {
void onAttachView(V view, M model);
void onDetachView(V View);
}
public abstract class MVPPresenter implements BasePresenter {
protected V mView;
protected M mModel;
protected DataManager mDataManager;
private CompositeSubscription mCompositeSubscription;
public MVPPresenter() {
//获取data module的DataManeger
mDataManager = App.getInstance().getAppComponent().getDataManeger();
}
@Override
public void onAttachView(V view, M model) {
this.mView = view;
this.mModel = model;
}
@Override
public void onDetachView(V View) {
onUnSubscribe();
}
/**
* rxJava取消订阅
*/
private void onUnSubscribe() {
if (null != mCompositeSubscription && mCompositeSubscription.hasSubscriptions()) {
mCompositeSubscription.unsubscribe();
}
}
/**
* 统一处理观察者与被观察者的线程
* @param observable
* @param subscriber
* @param
*/
public void addSubscription(Observable observable, Subscriber subscriber) {
if (null == mCompositeSubscription) {
mCompositeSubscription = new CompositeSubscription();
}
Subscription subscribe = observable.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(subscriber);
mCompositeSubscription.add(subscribe);
}
}
public abstract class BaseActivity extends AppCompatActivity {
protected String TAG = "NotInit";
private Context mContext;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(onGetLayoutResId());
ButterKnife.bind(this);
mContext = this;
TAG = this.getClass().getSimpleName();
}
/**
* 获取上下文
* @return
*/
protected Context getContext() {
return mContext;
}
/**
* 获取布局资源id
* @return
*/
protected abstract int onGetLayoutResId();
}
public abstract class BaseMVPActivity extends BaseActivity implements BaseView {
protected P mPresenter;
protected M mModel;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mPresenter = TUtil.getT(this, 0);
mModel = TUtil.getT(this, 1);
//绑定
mPresenter.onAttachView(this, mModel);
}
@Override
protected void onDestroy() {
super.onDestroy();
//解除绑定
if (null != mPresenter) {
mPresenter.onDetachView(this);
}
}
}
到这里整个网络请求与MVP的封装已完成,
ui包里面,建议一个功能模块一个包,我这里是main模块,所以建了个main包
public class MainActivity extends BaseMVPActivity implements MainContact.View {
@BindView(R.id.btn_main_start)
Button mBtnMainStart;
@BindView(R.id.tv_main_content)
TextView mTvMainContent;
@Override
protected int onGetLayoutResId() {
return R.layout.activity_main;
}
@Override
public void onLoadDataSuccess() {
mTvMainContent.setText(mPresenter.getData().toString());
Log.d(TAG, "onLoadDataSuccess,data:" + mPresenter.getData().toString());
}
@Override
public void onLoadDataError(String message) {
Log.d(TAG, "onLoadDataError,message:" + message);
}
@OnClick(R.id.btn_main_start)
public void onViewClicked() {
mPresenter.onLoadData();
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ButterKnife.bind(this);
}
}
public class MainContact {
interface Presenter extends BasePresenter {
void onLoadData();
MainResultBean getData();
}
interface View extends BaseView {
void onLoadDataSuccess();
void onLoadDataError(String message);
}
interface Model extends BaseModel {
//对数据进行处理完后返回给View或者是Presenter
MainResultBean disPoseNewsBean(MainResultBean newsBean);
}
}
public class MainModel implements MainContact.Model {
//在这里对数据进行处理。
@Override
public MainResultBean disPoseNewsBean(MainResultBean newsBean) {
newsBean.getStories().get(0).setTitle("我是经过处理后的标题");
return newsBean;
}
}
public class MainPresenter extends MVPPresenter implements MainContact.Presenter {
private static final String TAG = "MainPresenter";
private MainResultBean mDataBean;
@Override
public void onLoadData() {
addSubscription(mDataManager.mRepository.requestMainData(), new Subscriber() {
@Override
public void onCompleted() {
Log.d(TAG, "onCompleted:");
}
@Override
public void onError(Throwable e) {
Log.d(TAG, "onError,e:" + e.getMessage());
mView.onLoadDataError(e.getMessage());
}
@Override
public void onNext(MainResultBean resultBean) {
Log.d(TAG, "onNext:");
mDataBean = resultBean;
mView.onLoadDataSuccess();
}
});
}
@Override
public MainResultBean getData() {
return mDataBean;
}
}
到这里整个架构的搭建已完成,当然这个架构只列出了主要的MVP和网络封装,还有一些细节需要完善。
整个架构主要是让View和Presenter之间相互引用互调方法,使用这种设计模式,代码的流程和结构会清晰很多,View主要负责ui操作,Presenter则负责处理具体的业务逻辑。