RxJava + Retrofit + MVP(看完还不明白,吐槽我。适合初学者,VIP版MVP框架!!)

}
}

sbf.append(“\n收到响应: code ==> " + response.code())
.append(”\nResponse: " + rBody);
LogUtils.i(“网络请求”, sbf.toString());

return response;
}
}

看看打印出来的效果,很清晰哦:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

看这一点,要打印请求参数,返回参数,head等信息还是要通过okhttp的拦截器去做。这是吐槽Retrofit封装的一点

4、MVP开发框架

首先是我个人观点。此框架适合大型一点项目,且此框架是代码逻辑简洁,清晰,分离出视图层和Model层逻辑处理,适合做单元测试,且使activity里的代码减少,而且不会因为有些线程,异步的处理,有activity的引用导致无法回收,引起一系列问题。还是要强调一下只是代码逻辑简洁,不是代码简洁。因为他要增加很多类。那么来说说怎么代码逻辑简洁(适合其他人接手项目,和团队开发):

4.1、先看看项目的分包

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

首先google官方demo,也是把功能页面模块化了。这样你看我的分包,结合我的图片展示一看就明白

  • downfragemnt---->就是下载文件的页面
  • getfragment----->get请求的页面
  • main------------>mianActivity页面
  • postfragment----->post请求页面
  • uploadfragment---->上传文件页面

是不是一看就很清楚,比如getfragment的所有东西都在里面。当然你还可以在里面继续分包

4.2、在来看看契约类,个人觉得更加清晰,我们来看看get的器乐类GetContract

public interface GetContract {

//view只有2个更新ui的方法
interface View extends BaseView {
// 1、获取get数据,更新ui
void showGetData(String data);

// 2、获取get数据失败,更新ui
void showGetError(String msg);
}

//get的prensenter只有一个获取get数据的数据请求
interface Prensenter {
// 1、开启get网络请求
public void getGetData(String params);
}
}

比如你要看一个页面有什么更新UI的操作或者有什么网络请求,只要看契约类就对这个页面很了解了如:

1、view就是相当于MVP的V层,一般被activity或者Fragment实现,可以看到view里有2个方法:

  • showGetData 获取get请求数据,更新UI
  • showGetError get请求失败了,更新失败UI
  • BaseView 放的都是通用的方法,这里放了2个:showLoading,hideLoading(当然有些网络请求不需要转loading,那么不调用就好了)

2、Prensenter就是MVP的P层需要使用到的方法,要搞清楚,其实还有一个实体类GetPresenter。实体类实现GetContract.Prensenter。可以看到里面就一个getGetData。的网络请求。为什么这么写,第一契约类可以减少类的数目,第二更重要的一点是你可以很快的清楚你开发模块的功能和操作

还有一点要注意,因为使用RxJava结合Retrofit,我把通用的方法全部封装了BasePresenter里。因为RxJava的链式编程,所以我直接省略掉了model层,当然你可以写一个接口,然后写个model层把数据回调给Presenter。这里要注意MVP,MVP只是开发框架,是我们借鉴的开发思路。可能100个人有100个不同的MVP框架,这里我是说说我的想法,大家可以借鉴和学习。

5、RxJava结合Retrofit的MVP

5.1、封装Retrofit,其实和OkHttp没有区别

public class RetrofitManager {
//省略部分代码,便于理解
private static RetrofitManager retrofitManager;
private OkHttpClient okHttpClient;
private Retrofit retrofit;
//这是我retrofit的网络请求配置
private RetrofitApiService retrofitApiService;

private RetrofitManager() {
//初始化Okhttp
initOkHttpClient();
//初始化retrofit
initRetrofit();
}

public static RetrofitManager getRetrofitManager() {
if (retrofitManager == null) {
synchronized (RetrofitManager.class) {
if (retrofitManager == null) {
retrofitManager = new RetrofitManager();
}
}
}
return retrofitManager;
}

private void initRetrofit() {
retrofit = new Retrofit.Builder()
.baseUrl(SystemConst.DEFAULT_SERVER)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.client(okHttpClient)
.build();
retrofitApiService = retrofit.create(RetrofitApiService.class);
}

public static RetrofitApiService getApiService() {
return retrofitManager.retrofitApiService;
}

private void initOkHttpClient() {
okHttpClient = new OkHttpClient.Builder()
//设置缓存文件路径,和文件大小
.cache(new Cache(new File(Environment.getExternalStorageDirectory() + “/okhttp_cache/”), 50 * 1024 * 1024))
.connectTimeout(10, TimeUnit.SECONDS)
.readTimeout(10, TimeUnit.SECONDS)
.writeTimeout(10, TimeUnit.SECONDS)
.addInterceptor(new HttpLogInterceptor())
//设置在线和离线缓存
.addInterceptor(OfflineCacheInterceptor.getInstance())
.addNetworkInterceptor(NetCacheInterceptor.getInstance())
.build();
}
}

5.2、比如我们来写GetFragment这块。首先写契约类

回想之前我们有个BaseView。里面有2个方法showLoading和hideLoading (只要记住大家通用的方法封装成base,有些页面不同就不调用就行了) 代码如下:

public interface BaseView {

//显示正在加载loading
void showLoading(String message);

// 关闭正在加载loading
void hideLoading();

//防止RxJava内存泄漏,可以暂且忽略
LifecycleTransformer bindLifecycle();

}

那么GetFragment契约类就是(还要说下这里的presenter接口只是GetPresenter所要用的方法,放在契约类里,一目了然):

public interface GetContract {

//view只有2个更新ui的方法
interface View extends BaseView {
// 1、获取get数据,更新ui
void showGetData(String data);

// 2、获取get数据失败,更新ui
void showGetError(String msg);
}

//get的prensenter只有一个获取get数据的数据请求
interface Prensenter {
// 1、开启get网络请求
public void getGetData(String params);
}
}

5.3、接下来是GetPresenter的实体类,当然这里有个BasePresenter(以下讲解移除部分代码更清晰)

我们想象有什么通用方法是在BasePresenter里的?当然你可以把一些复杂的写很多步骤的网络请求封装在这里,比如我们项目里的下载文件等,这里我们讲简单的通用方法

GetPresenter需要view的引用 所以有:1、setView加入引用 2、view = null置空引用,防止oom

//这个是为了退出页面,取消请求的
public CompositeDisposable compositeDisposable;
// 绑定的view
private V mvpView;
//绑定view,一般在初始化中调用该方法
public void attachView(V mvpView) {
this.mvpView = mvpView;
compositeDisposable = new CompositeDisposable();
}
//置空view,一般在onDestroy中调用
public void detachView() {
this.mvpView = null;
//退出页面的时候移除所有网络请求
removeDisposable();
}
//需要退出页面移除网络请求的加入进来
public void addDisposable(Disposable disposable) {
compositeDisposable.add(disposable);
}
//退出页面移除所有网络请求
public void removeDisposable() {
if (compositeDisposable != null) {
compositeDisposable.dispose();
}
}

使用一个方法快速获取RetrofitManager里的网络配置

public RetrofitApiService apiService() {
return RetrofitManager.getRetrofitManager().getApiService();
}

大部分的网络请求都有showLoading和hideLoading,还有线程切换,封装进来

//这里我多加了个是否显示loading的标识和loading上的文字,想偷懒可以用方法重载把这2个参数默认
public Observable observe(Observable observable, final boolean showDialog, final String message) {
return observable.subscribeOn(Schedulers.io())
.doOnSubscribe(new Consumer() {
@Override
public void accept(Disposable disposable) throws Exception {
if (showDialog) {
mvpView.showLoading(message);
}
}
})
.subscribeOn(AndroidSchedulers.mainThread())
.doFinally(new Action() {
@Override
public void run() throws Exception {
if (showDialog) {
mvpView.hideLoading();
}
}
})
.observeOn(AndroidSchedulers.mainThread())
//防止RxJava内存泄漏
.compose(mvpView.bindLifecycle());
}

那么我们的BasePresenter(移除部分代码更清晰)

//这里加上泛型,第一在使用Presenter一眼就看出对应哪个View,其次确定我们V的类型
public abstract class BasePresenter {
public CompositeDisposable compositeDisposable;

private V mvpView;

public void attachView(V mvpView) {
this.mvpView = mvpView;
compositeDisposable = new CompositeDisposable();
}
public void detachView() {
this.mvpView = null;
removeDisposable();
}
//检查是否有view的引用
public boolean isViewAttached() {
return mvpView != null;
}

//获取view的引用
public V getView() {
return mvpView;
}

public RetrofitApiService apiService() {
return RetrofitManager.getRetrofitManager().getApiService();
}
//需要退出页面移除网络请求的加入进来
public void addDisposable(Disposable disposable) { }

//退出页面移除所有网络请求
public void removeDisposable() {}

//省的写线程切换和showloading和hide的复杂操作
public Observable observe(Observable observable, final boolean showDialog, final String message) {}

}

那么GetPresenter就是这样

//省略部分代码,便于理解。实体GetPresenter实现GetContract.Prensenter接口,里面就一个getGetData方法
public class GetPresenter extends BasePresenter<GetContract.View> implements GetContract.Prensenter {

@Override
public void getGetData(String params) {
if (!isViewAttached()) {
//如果没有View引用就不加载数据
return;
}
//BasePresenter里有了封装,切换线程和放置内存泄漏的 .compose(mvpView.bindLifecycle())都不用写了
//代码越能偷懒,说明框架越是封装的完美
observe(apiService().getGank(params))
.subscribe(new Consumer() {
@Override
public void accept(GankFatherBean gankFatherBean) throws Exception {
getView().showGetData(gankFatherBean.getTitle());
}
}, new Consumer() {
@Override
public void accept(Throwable throwable) throws Exception {
getView().showGetError(throwable.toString());
}
});

}
}

5.4、其次是BaseFragment

因为使用RxJava,如果使用不当很容易造成RxJava内存泄漏,所以官方也出了方法继承RxFragment

因为fragment是作为view是要实现view接口的,同时每个fragment都要有presenter去调用方法
初步如下(省了部分代码,便于理解):

public abstract class BaseFragment extends RxFragment implements BaseView {
public T mPresenter;
public abstract T cretaePresenter();
protected View mContentView;
private Unbinder mUnbinder;

@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
// 避免多次从xml中加载布局文件
mPresenter = cretaePresenter();
if (mPresenter != null) {
mPresenter.attachView(this);
}
return mContentView;
}

@Override
public void onDestroy() {
super.onDestroy();
if (mPresenter != null) {
mPresenter.detachView();
mPresenter = null;
}
}

@Override
public void showLoading(String message) {
LoadingDialog.getInstance().show(getActivity(), message);
}

@Override
public void hideLoading() {
LoadingDialog.getInstance().dismiss();
}

//防止Rx内存泄漏
@Override
public LifecycleTransformer bindLifecycle() {
LifecycleTransformer objectLifecycleTransformer = bindToLifecycle();
return objectLifecycleTransformer;
}
}

5.5、在GetFragment里使用就是这样(省略部分代码,便于理解)

public class GETFragment extends BaseFragment implements GetContract.View {
@BindView(R.id.txt_content) TextView txt_content;

@Override
public GetPresenter cretaePresenter() {
return new GetPresenter();
}

@Override
public int getContentViewId() {
return R.layout.fragment_get;
}

//处理逻辑
@Override
protected void processLogic(Bundle savedInstanceState) {

}

@OnClick(R.id.txt_get)
public void getClick() {
//请求网络
mPresenter.getGetData(“Android”);
}

@Override
public void showGetData(String data) {
txt_content.setText(data);
}

@Override
public void showGetError(String msg) {
ToastUtils.showToast(msg);
}
}

6、断网重连

因为使用了强大的RxJava,这里断网重连用的就是操作符retryWhen,封装在BasePresenter里的observeWithRetry。这里就不多讲了,可以先把操作符retryWhen了解清楚就看明白了

7、取消网络请求

这里的返回值就是一个disposable,如果主动取消就直接调 disposable.dispose();当然我这里也封装了离开页面取消请求你可以把它加到addDisposable(Disposable disposable)里。就不用管了

Disposable disposable = observe(apiService().getGank(params))
.subscribe(new Consumer() {
@Override
public void accept(GankFatherBean gankFatherBean) throws Exception {
getView().showGetData(gankFatherBean.getTitle());
}
}, new Consumer() {
@Override
public void accept(Throwable throwable) throws Exception {
getView().showGetError(throwable.toString());
}
});

8、多次请求同一网络,只请求一次

尾声

面试成功其实都是必然发生的事情,因为在此之前我做足了充分的准备工作,不单单是纯粹的刷题,更多的还会去刷一些Android核心架构进阶知识点,比如:JVM、高并发、多线程、缓存、热修复设计、插件化框架解读、组件化框架设计、图片加载框架、网络、设计模式、设计思想与代码质量优化、程序性能优化、开发效率优化、设计模式、负载均衡、算法、数据结构、高级UI晋升、Framework内核解析、Android组件内核等。

不仅有学习文档,视频+笔记提高学习效率,还能稳固你的知识,形成良好的系统的知识体系。这里,笔者分享一份从架构哲学的层面来剖析的视频及资料分享给大家梳理了多年的架构经验,筹备近6个月最新录制的,相信这份视频能给你带来不一样的启发、收获。

Android进阶学习资料库

一共十个专题,包括了Android进阶所有学习资料,Android进阶视频,Flutter,java基础,kotlin,NDK模块,计算机网络,数据结构与算法,微信小程序,面试题解析,framework源码!

image

大厂面试真题

PS:之前因为秋招收集的二十套一二线互联网公司Android面试真题 (含BAT、小米、华为、美团、滴滴)和我自己整理Android复习笔记(包含Android基础知识点、Android扩展知识点、Android源码解析、设计模式汇总、Gradle知识点、常见算法题汇总。)

《2017-2021字节跳动Android面试历年真题解析》


《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》点击传送门,即可获取!
,计算机网络,数据结构与算法,微信小程序,面试题解析,framework源码!

[外链图片转存中…(img-HeqsymFp-1715533267666)]

大厂面试真题

PS:之前因为秋招收集的二十套一二线互联网公司Android面试真题 (含BAT、小米、华为、美团、滴滴)和我自己整理Android复习笔记(包含Android基础知识点、Android扩展知识点、Android源码解析、设计模式汇总、Gradle知识点、常见算法题汇总。)

[外链图片转存中…(img-6oILA9He-1715533267668)]

《2017-2021字节跳动Android面试历年真题解析》

[外链图片转存中…(img-5znBD3YW-1715533267670)]
《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》点击传送门,即可获取!

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
对于Android项目中的网络请求,RxJavaRetrofitMVP是常用的框架组合。下面是一个简单的网络框架封装示例: 首先,在项目中引入RxJavaRetrofit的依赖。 ``` implementation 'io.reactivex.rxjava2:rxjava:2.2.19' implementation 'io.reactivex.rxjava2:rxandroid:2.1.1' implementation 'com.squareup.retrofit2:retrofit:2.9.0' implementation 'com.squareup.retrofit2:converter-gson:2.9.0' implementation 'com.squareup.retrofit2:adapter-rxjava2:2.9.0' ``` 然后,创建一个Retrofit的单例类,用于进行网络请求的初始化和配置。 ```java public class RetrofitClient { private static Retrofit retrofit; private static final String BASE_URL = "https://api.example.com/"; public static Retrofit getClient() { if (retrofit == null) { retrofit = new Retrofit.Builder() .baseUrl(BASE_URL) .addConverterFactory(GsonConverterFactory.create()) .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .build(); } return retrofit; } } ``` 接下来,创建一个ApiService接口,定义网络请求的方法。 ```java public interface ApiService { @GET("users") Observable<List<User>> getUsers(); } ``` 然后,创建一个DataManager类,用于管理网络请求。 ```java public class DataManager { private ApiService apiService; public DataManager() { apiService = RetrofitClient.getClient().create(ApiService.class); } public Observable<List<User>> getUsers() { return apiService.getUsers(); } } ``` 最后,在MVP的Presenter中调用DataManager类进行网络请求。 ```java public class UserPresenter { private UserView userView; private DataManager dataManager; public UserPresenter(UserView userView) { this.userView = userView; dataManager = new DataManager(); } public void getUsers() { dataManager.getUsers() .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Observer<List<User>>() { @Override public void onSubscribe(Disposable d) { // 在请求开始时的操作 } @Override public void onNext(List<User> users) { // 请求成功返回数据时的操作 userView.showUsers(users); } @Override public void onError(Throwable e) { // 请求失败时的操作 userView.showError(e.getMessage()); } @Override public void onComplete() { // 请求成时的操作 } }); } } ``` 这样,就成了一个简单的Android RxJava + Retrofit + MVP网络框架封装。你可以根据自己的需要,进行进一步的封装和扩展。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值