Android MVP入门到进阶之- 系统框架集成(完结)

前言

本系列共三篇:
Android MVP入门到进阶之-简单入门
Android MVP入门到进阶之-结合Dagger2
Android MVP入门到进阶之- 系统框架集成(完结)

通过前两篇文章,整理了 MVP的简单框架的搭建MVP结合Dagger2 的使用的例子,如果你还不熟悉MVP的使用请先查看前两篇文章:
Android MVP入门到进阶之-简单入门
Android MVP入门到进阶之-结合Dagger2
这篇文章我们我们主要介绍,MVP 配合网络框架Retrofit 的使用,因为我们APP开发,网络请求是很重要的一环,当然你也可以选择自己喜欢的网络框架进行封装。这里我们只讲解 Retrofit2 基于 Dagger2的封装和在MVP框架中的使用
如果你还不知道什么事Retrofit是什么,你可能还需要补充一下知识
你真的会用Retrofit2吗?Retrofit2完全教程

正式开始

通过Android MVP入门到进阶之-结合Dagger2的封装之后,我们的主体框架已经定型,所以我们只需要添加一个HttpMoudle就可以了,我们一步一步来添加

1. 在build.gradle中添加相关依赖

    /*gson 用于解析json数据*/
    implementation 'com.google.code.gson:gson:2.8.2'
    /*retrofit 网络请求框架 + rxjava */
    implementation 'com.squareup.retrofit2:retrofit:2.3.0'
    /*添加Gson适配器*/
    implementation 'com.squareup.retrofit2:converter-gson:2.3.0'
    implementation 'com.squareup.retrofit2:adapter-rxjava2:2.3.0'
    implementation 'com.squareup.retrofit2:converter-scalars:2.0.0'
    /*okhttp日志打印*/
    implementation 'com.squareup.okhttp3:logging-interceptor:3.6.0'
    /*rxjava*/
    implementation 'io.reactivex.rxjava2:rxandroid:2.0.1'
    implementation 'io.reactivex.rxjava2:rxjava:2.1.8'

2. 在AndroidManifest.xml 中添加网络权限

    <!-- 用于访问网络,网络定位需要上网 -->
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.INTERNET" />

添加BaseApiService接口 用于管理网络请求接口和提供网络请求的方法

/**
 * @desc BaseApiService   为Retrofit框架提供接口请求注解,也是我们的网络接口管理类
 * @author Marlon
 * @date 2018/12/18
 */

public interface BaseApiService {
    String BASE_URL_ZHIHU = " http://news-at.zhihu.com/";

    @GET("/api/4/version/android/2.3.0")
    Observable<BaseResponse<Resond>> getVerisionRxjava();
}

书写HttpMoudel

/**
 * @desc HttpModule
 * @author Marlon
 * @date 2017/12/18
 */
@Module
public class HttpModule {
    private static final String TAG = "HttpModule";
    private static final long TIMEOUT = 1000;

    @Singleton
    @Provides
        //构建 Retrofit.Builder
    Retrofit.Builder provideRetrofitBuilder() {
        return new Retrofit.Builder();
    }

    @Singleton
    @Provides
        // 构建 OkHttpClient.Builder
    OkHttpClient.Builder provideOkHttpBuilder() {
        return new OkHttpClient.Builder();
    }

    @Singleton
    @Provides
        //构建 OkHttpClient 这里的拦截器 根据需求添加 需要才添加
    OkHttpClient provideClient(OkHttpClient.Builder builder) {
        CookieManger cookieJar =
                new CookieManger(App.getInstance());
        //储存目录
        File mFile = new File(App.getInstance().getCacheDir() + "http");
        // 10 MB 最大缓存数
        long maxSize = 10 * 1024 * 1024;
        Cache mCache = new Cache(mFile, maxSize);
        Map<String, String> headers = new HashMap<>();
        return builder
                //添加Cookie管理,不需要管理可以不加,token在Cookie中的时候需要添加
                .cookieJar(cookieJar)
                //添加统一的请求头
                .addInterceptor(new BaseInterceptor(headers))
                //添加base改变拦截器
                .addInterceptor(new BaseUrlInterceptor())
                //添加缓存拦截器
                .addNetworkInterceptor(new CaheInterceptor(App.getInstance()))
                //打印请求信息(可以自定义打印的级别!!)
                .addNetworkInterceptor(new HttpLoggingInterceptor(message -> Log.e(TAG, message)).setLevel(HttpLoggingInterceptor.Level.BODY))
                //相关请求时间设置
                //链接时间
                .connectTimeout(TIMEOUT, TimeUnit.SECONDS)
                //读取时间
                .readTimeout(TIMEOUT, TimeUnit.SECONDS)
                //写入时间
                .writeTimeout(TIMEOUT, TimeUnit.SECONDS)
                //添加缓存
                .cache(mCache)
                // 这里你可以根据自己的机型设置同时连接的个数和时间,我这里8个,和每个保持时间为15s
                .connectionPool(new ConnectionPool(8, 15, TimeUnit.SECONDS))
                .build();

    }

    @Singleton
    @Provides
        //构建 Retrofit
    Retrofit provideMyRetrofit(Retrofit.Builder builder, OkHttpClient client) {
        return createRetrofit(builder, client, BaseApiService.BASE_URL_ZHIHU);
    }


    @Singleton
    @Provides
        //通过 反射机制 创建BaseApiService  这里BaseApiService 是封装请求方法的接口类
    BaseApiService provideMyService(Retrofit retrofit) {
        return retrofit.create(BaseApiService.class);
    }

    /**
     * 通过Retrofit.Builder OkHttpClient url 构建Retrofit
     * @param builder
     * @param client
     * @param url
     * @return
     */
    private Retrofit createRetrofit(Retrofit.Builder builder, OkHttpClient client, String url) {
        return builder.baseUrl(url)
                .client(client)
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .build();
    }

}

上面构建OkHttpClient 的方法中涉及到很多的拦截器,详细内容请查看源码demo

在 AppComponent中添加一下内容,将HttpModule 添加到注解中

/**
 * @desc AppComponent
 * @author Marlon
 * @date 2018/12/18
 */

@Singleton
@Component(modules = {AppModule.class, HttpModule.class})
public interface AppComponent {

    App getContext();  // 提供App的Context

    BaseApiService retrofitHelper();  //提供http的帮助类

}

在APP中加入HttpModule 关联

/**
 * @desc App
 * @author Marlon
 * @date 2018/12/18
 */

public class App extends Application {
    private static App instance;
    public static AppComponent appComponent;

    @Override
    public void onCreate() {
        super.onCreate();
        instance = this;
    }

    public static synchronized App getInstance() {
        return instance;
    }

    public static AppComponent getAppComponent() {
        if (appComponent == null) {
            appComponent = DaggerAppComponent.builder()
                    .appModule(new AppModule(instance))
                    .httpModule(new HttpModule())//这里添加
                    .build();
        }
        return appComponent;
    }

    public static void exitApp() {
        try {
            ActivityCollector.removeAllActivity();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            System.exit(0);
        }
    }
}

书写 RxPresenter 类使用

/**
 * @desc RxPresenter 基于Rx的Presenter封装,控制订阅的生命周期
 * @author Marlon
 * @date 2018/12/18
 */
public class RxPresenter<T extends BaseView> implements BasePresenter<T> {
    protected BaseApiService apiService;
    protected Context mContext;
    protected T mView;
    private CompositeDisposable mCompositeDisposable;

    public RxPresenter(App mContext, BaseApiService apiService) {
        this.apiService = apiService;
        this.mContext = mContext;
    }

    /**
     * 取消注册 中断请求
     */
    protected void unSubscribe() {
        if (mCompositeDisposable != null) {
            mCompositeDisposable.dispose();
            mCompositeDisposable.clear();
        }
    }

    //注册
    protected void addSubscribe(Disposable subscription) {
        if (mCompositeDisposable == null) {
            mCompositeDisposable = new CompositeDisposable();
        }
        mCompositeDisposable.add(subscription);
    }

    protected void addSubscribe(Observable<?> observable, BaseObserver observer) {
        if (mCompositeDisposable == null) {
            mCompositeDisposable = new CompositeDisposable();
        }
        mCompositeDisposable.add(observable.compose(RxHelper.io_main(mContext)).subscribeWith(observer));
    }

    @Override
    public void attachView(T view) {
        this.mView = view;
    }

    @Override
    public void detachView() {
        this.mView = null;
        unSubscribe();
    }
}

MainPresenter 继承 RxPresenter

/**
 * @desc MainPresenter
 * @author Marlon
 * @date 2018/12/18
 */
public class MainPresenter extends RxPresenter<MainContract.View> implements MainContract.Presenter {
    @Inject
    public MainPresenter(App app, BaseApiService service) {
        super(app, service);
    }


    @Override
    public void getVersion() {
        //使用方式一
        addSubscribe(apiService.getVerisionRxjava()
                .compose(RxHelper.io_main(mContext))
                .subscribeWith(new BaseObserver<Resond>() {
                    @Override
                    protected void onSuccess(Resond value) {
                        mView.showData(value.toString());
                    }


                    @Override
                    protected void onFailure(String message) {
                        mView.showData(message);
                    }
                }));
        //使用方式二
        addSubscribe(apiService.getVerisionRxjava(), new BaseObserver<Resond>() {

            @Override
            protected void onSuccess(Resond value) {

            }

            @Override
            protected void onFailure(String message) {

            }
        });
    }
}

总结

到这里 我们框架就完全封装完成,可能你看到这里还很迷,确实我刚开始学的时候也很迷,所以你需要把
RxJava 2、Retrofit2、Dagger2 ,慢慢搞懂,然后照着demo写一遍,理解一下,应该还是不难,感觉用文字叙述实在是不好写,如果有疑问,也可以留言哈,我明白的可以答疑。
本文源码地址demo,如果对你有帮助,希望点一下小星星哈!
到此,我们MVP框架系列已经完结了。。。后面可能回再写一篇结合组件化的博客,以后再说吧。

本文章为原创博客,转载请注明出处!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,772评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,458评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,610评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,640评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,657评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,590评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,962评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,631评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,870评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,611评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,704评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,386评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,969评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,944评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,179评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,742评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,440评论 2 342