基于MVP + Dagger2 + RxJava + Retrofit + OkHttp的android架构

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/yangyin3096/article/details/80010849

闲话不多说,直接上菜。。。

project的结构

整个project的结构由data module和app module组成:

  • data module:数据模块,封装了网络请求及数据处理
    api包:网络接口api
    bean包:数据实体
    di包:Dagger2相关类
    repository包:网络请求的仓库
  • app module:主模块
    base包:基类
    di包:Dagger2相关类
    ui包:ui模块的类
    util包:工具类
    这里写图片描述

需要添加的依赖

  • data 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"
  • app module
/*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'

data module

  • ApiService
public interface ApiService {
    @GET("news/latest")
    Observable<MainResultBean> requestMainData();
}
  • Repository
public class Repository {

    private ApiService mApiService;

    public Repository(ApiService apiService) {
        mApiService = apiService;
    }

    public Observable<MainResultBean> requestMainData() {
        return mApiService.requestMainData();
    }
}
  • DataModule
@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);
    }

}
  • DataManager
public class DataManager {

    @Inject
    public Repository mRepository;

    public DataManager() {
        DaggerDataComponent.builder().dataModule(new DataModule()).build().injectDataManager(this);
    }
}
  • DataComponent
@Singleton
@Component(modules = DataModule.class)
public interface DataComponent {
    void injectDataManager(DataManager dataManager);
}

app module

  • AppModule
@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();
    }
}
  • AppComponent
@Singleton
@Component(modules = AppModule.class)
public interface AppComponent {

    void injectApp(App app);

    Application getApplication();

    DataManager getDataManeger();
}
  • App
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;
    }
}
  • BaseModel
public interface BaseModel {
}
  • BaseView
public interface BaseView {
}
  • BasePresenter
public interface BasePresenter<V extends BaseView, M extends BaseModel> {

    void onAttachView(V view, M model);

    void onDetachView(V View);
}
  • MVPPresenter
public abstract class MVPPresenter<V extends BaseView, M extends BaseModel> implements BasePresenter<V, M> {

    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 <T>
     */
    public <T> void addSubscription(Observable<T> observable, Subscriber<T> subscriber) {
        if (null == mCompositeSubscription) {
            mCompositeSubscription = new CompositeSubscription();
        }
        Subscription subscribe = observable.subscribeOn(Schedulers.io())
                                            .observeOn(AndroidSchedulers.mainThread())
                                            .subscribe(subscriber);
        mCompositeSubscription.add(subscribe);
    }
}
  • BaseActivity
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();
}
  • BaseMVPActivity
public abstract class BaseMVPActivity<P extends BasePresenter, M extends BaseModel> 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模块使用

ui包里面,建议一个功能模块一个包,我这里是main模块,所以建了个main包

  • 结构
    这里写图片描述

  • MainActivity

public class MainActivity extends BaseMVPActivity<MainPresenter, MainModel> 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);
    }
}
  • MainContact
public class MainContact {

    interface Presenter extends BasePresenter<View, Model> {
        void onLoadData();
        MainResultBean getData();
    }

    interface View extends BaseView {
        void onLoadDataSuccess();
        void onLoadDataError(String message);
    }

    interface Model extends BaseModel {
        //对数据进行处理完后返回给View或者是Presenter
        MainResultBean disPoseNewsBean(MainResultBean newsBean);
    }
}
  • MainModel
public class MainModel implements MainContact.Model {

    //在这里对数据进行处理。
    @Override
    public MainResultBean disPoseNewsBean(MainResultBean newsBean) {
        newsBean.getStories().get(0).setTitle("我是经过处理后的标题");
        return newsBean;
    }
}
  • MainPresenter
public class MainPresenter extends MVPPresenter<MainContact.View, MainContact.Model> implements MainContact.Presenter {

    private static final String TAG = "MainPresenter";
    private MainResultBean mDataBean;

    @Override
    public void onLoadData() {
        addSubscription(mDataManager.mRepository.requestMainData(), new Subscriber<MainResultBean>() {
            @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则负责处理具体的业务逻辑。

猜你喜欢

转载自blog.csdn.net/yangyin3096/article/details/80010849