android mvp的好处,网上一搜一大堆,相对于一开始普通的在activity中处理所有的不管是网络请求还是页面渲染,最大的好处是简洁了,废话不多说,看代码

这里网络请求使用了两种,一种是自己封装的okhttp,一种是retrofit+rxjava,可以看出retrofit+rxjava的链式调用和普通的okhttp的区别

mvp,m-model 处理数据,v-activity渲染展示,p-persenter 用于连接m和v,其中又引入锲约类的概念,用于管理这三个所有的接口。

先看代码,

,为了方便我直接放在一个包里了,可以看到 有TestActivity,(mvp-v),TestModel(mvp-m),TestPersenter(mvp-p),其中TestContract就是契约类,用于管理用到的所有接口,多了一个TestCallback用于使用自己封装的okhttp回调,使用retrofit+rxjava时可以省略,这其中也有人习惯把TestModel省略,直接在Persenter中处理数据然后在view中返回。

先看契约类,其中BaseView可以提取一些公共的方法

public interface TestContract {

    interface TestModel{
void getData(String id,TestCallback callback);
Observable<HomePage> getData();
} interface TestPersenter{
void getData(String id);
}
    interface TestView extends BaseView {
void SetData(HomePage homePage);
}
 }
public interface BaseView {

    void Toast(String s);

    /**
* 绑定Android生命周期 防止RxJava内存泄漏
*
* @param <T>
* @return
*/
<T> AutoDisposeConverter<T> bindAutoDispose(); }

可以清楚的看到,model,persenter,view使用到的接口。

再看activity中,implements  TestContract.TestView接口,必须实现接口中的方法----SetData,定义了一个按钮,一个TextView,点击按钮,获取数据,显示在TextView中,其中TestPersenter testPersenter = new TestPersenter(this);体现了persenter的连接作用,获取到实例,调用persenter中的getData方法,


public class TestActivity extends BaseActivity implements TestContract.TestView {

TestPersenter testPersenter = new TestPersenter(this);

@BindView(R.id.button)
Button button;
@BindView(R.id.testview)
TextView testview;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
ButterKnife.bind(this);

button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
testPersenter.getData("1");
}
});
}

@Override
public void SetData(HomePage homePage) {
testview.setText(homePage.getMessage());
}

@Override
public void Toast(String s) {
super.Toast(s);

}
}
 
public class BaseActivity extends AppCompatActivity implements BaseView {

    @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_base2);
Window window = getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
getSupportActionBar().hide();
ImmersionBar.with(this)
.statusBarColor(R.color.bar) //状态栏颜色,不写默认透明色
.statusBarDarkFont(true) //原理:如果当前设备支持状态栏字体变色,会设置状态栏字体为黑色,如果当前设备不支持状态栏字体变色,会使当前状态栏加上透明度,否则不执行透明度
.fitsSystemWindows(true)
.keyboardEnable(true)
.init(); } @Override
protected void onDestroy() {
super.onDestroy();
// 必须调用该方法,防止内存泄漏
ImmersionBar.destroy(this,null);
}
/**
* 绑定生命周期 防止MVP内存泄漏
*
* @param <T>
* @return
*/
@Override
public <T> AutoDisposeConverter<T> bindAutoDispose() {
return AutoDispose.autoDisposable(AndroidLifecycleScopeProvider
.from(this, Lifecycle.Event.ON_DESTROY));
} @Override
public void Toast(String s) { }
}

TestPersenter,首先implements 接口,实现接口中的方法---getData,其次拿到了model和view,在getData方法中,调用model获取数据,调用view的setData方法展示数据到页面,从这里也可以看出persenter的连接作用,连接model和view。

public class TestPersenter implements TestContract.TestPersenter{

    TestContract.TestModel model ;
TestContract.TestView testView; public TestPersenter(TestContract.TestView testView) {
this.testView = testView;
this.model = new TestModel();
} @Override
public void getData(String id) {
model.getData("1", new TestCallback() {
@Override
public <T> void success(T enty) {
testView.SetData((HomePage) enty);
} @Override
public void error(String msg) { }
});
}
}

model:同样implements接口,实现接口中的方法getData,第一个方法是使用自己封装的okhttp网络类,在这里就看出TestCallback 的作用了,访问接口获取数据后,通过TestCallback 返回,TestCallback 中只定义了两个简单的,一个成功时的回调,一个失败时的回调


public class TestModel implements TestContract.TestModel {

@Override
public void getData(String id, TestCallback callback) {
new OkHttpUtil().getJson(HttpUrl.homePage, new OkHttpUtil.HttpCallBack() {
@Override
public void onSusscess(String data) throws JSONException, ParseException {
HomePage homePage = new Gson().fromJson(data,HomePage.class);
if(homePage.isSuccess()){
callback.success(homePage);
}else{
callback.error(homePage.getMessage());
}
}

@Override
public void onError(String meg) {
super.onError(meg);
callback.error(meg);
}
});
}

@Override
public Observable<HomePage> getData() {
       return RetrofitClient.getInstance().getApi().GetData();
    }
}
 
public interface TestCallback {
<T> void success(T enty); void error(String msg);
}

使用retrofit+rxjava,可以看到,省略了TestCallback回调,直接链式调用,onNext中调用了view的setData方法显示数据。

public class TestPersenter implements TestContract.TestPersenter{

    TestContract.TestModel model ;
TestContract.TestView testView; public TestPersenter(TestContract.TestView testView) {
this.testView = testView;
this.model = new TestModel();
} @Override
public void getData(String id) {
// model.getData("1", new TestCallback() {
// @Override
// public <T> void success(T enty) {
// testView.SetData((HomePage) enty);
// }
//
// @Override
// public void error(String msg) {
//
// }
// }); model.getData()
.compose(RxScheduler.Obs_io_main())
.to(studyView.bindAutoDispose())
.subscribe(new Observer<HomePage>() {
@Override
public void onSubscribe(@NonNull Disposable d) { } @Override
public void onNext(@NonNull HomePage homePage) {
testView.SetData(homePage);
} @Override
public void onError(@NonNull Throwable e) {
) } @Override public void onComplete() { } }); } }

retrofit的使用到的方法

public interface APIService {

/**
* 首页数据
* @return
*/
@GET("app/home_page/queryList")
Observable<HomePage> GetData();

}
public class RetrofitClient {

    private static volatile RetrofitClient instance;
private APIService apiService;
private String baseUrl = "****";
private Retrofit retrofit;
private OkHttpClient okHttpClient; private RetrofitClient() {
} public static RetrofitClient getInstance() {
if (instance == null) {
synchronized (RetrofitClient.class) {
if (instance == null) {
instance = new RetrofitClient();
}
}
}
return instance;
} /**
* 设置Header
*
* @return
*/
private Interceptor getHeaderInterceptor() {
return new Interceptor() {
@Override
public Response intercept(@NonNull Chain chain) throws IOException {
Request original = chain.request();
Request.Builder requestBuilder = original.newBuilder();
//添加Token
// .header("token", "");
Request request = requestBuilder.build();
return chain.proceed(request);
}
}; } /**
* 设置拦截器 打印日志
*
* @return
*/
private Interceptor getInterceptor() { HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
//显示日志
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY); return interceptor;
} public OkHttpClient getOkHttpClient() {
if (okHttpClient == null) {
//如果为DEBUG 就打印日志
if (BuildConfig.DEBUG) {
okHttpClient = new OkHttpClient().newBuilder()
//设置Header
.addInterceptor(getHeaderInterceptor())
//设置拦截器
.addInterceptor(getInterceptor())
.build();
} else {
okHttpClient = new OkHttpClient().newBuilder()
//设置Header
.addInterceptor(getHeaderInterceptor())
.build();
} } return okHttpClient;
} public APIService getApi() {
//初始化一个client,不然retrofit会自己默认添加一个
if (retrofit == null) {
retrofit = new Retrofit.Builder()
//设置网络请求的Url地址
.baseUrl(baseUrl)
//设置数据解析器
.addConverterFactory(GsonConverterFactory.create())
//设置网络请求适配器,使其支持RxJava与RxAndroid
.addCallAdapterFactory(RxJava3CallAdapterFactory.create())
.client(getOkHttpClient())
.build();
}
//创建—— 网络请求接口—— 实例
if (apiService==null){
apiService = retrofit.create(APIService.class);
} return apiService;
} }
public class RxScheduler {

    /**
* 统一线程处理
*
* @param <T> 指定的泛型类型
* @return FlowableTransformer
*/
public static <T> FlowableTransformer< T, T> Flo_io_main() {
return new FlowableTransformer<T, T>() {
@Override
public Publisher<T> apply(Flowable<T> upstream) {
return upstream.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread());
}
};
} /**
* 统一线程处理
*
* @param <T> 指定的泛型类型
* @return ObservableTransformer
*/
public static <T> ObservableTransformer<T, T> Obs_io_main() {
return new ObservableTransformer<T, T>() {
@Override
public ObservableSource<T> apply( Observable<T> upstream) {
return upstream.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread());
}
};
} }
public interface BaseView {

    void Toast(String s);

    /**
* 绑定Android生命周期 防止RxJava内存泄漏
*
* @param <T>
* @return
*/
<T> AutoDisposeConverter<T> bindAutoDispose(); }
 //okhttp3
implementation 'com.squareup.okhttp3:okhttp:4.2.0'
implementation "com.squareup.okhttp3:logging-interceptor:3.10.0"
implementation 'com.google.code.gson:gson:2.8.6' //retrofit2
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
implementation 'com.squareup.retrofit2:adapter-rxjava3:2.9.0' //AutoDispose解决RxJava内存泄漏
implementation 'com.uber.autodispose2:autodispose:2.0.0'
implementation 'com.uber.autodispose2:autodispose-android:2.0.0'
implementation 'com.uber.autodispose2:autodispose-lifecycle:2.0.0'
implementation 'com.uber.autodispose2:autodispose-androidx-lifecycle:2.0.0'
  // 基础依赖包,必须要依赖
implementation 'com.gyf.immersionbar:immersionbar:3.0.0-beta07'
// fragment快速实现(可选)
implementation 'com.gyf.immersionbar:immersionbar-components:3.0.0-beta07'

至此,mvp框架结束,mvp增加了接口,使页面和数据处理分开,层次分明,后期好维护。在较小项目中,就几个页面,不必使用框架,也不必为了框架而使用,适合项目的才是最好的。

Android MVP框架 详细代码的更多相关文章

  1. 如何实现自己的Android MVP框架?

    相信熟悉android开发的童鞋对MVP框架应该都不陌生吧,网上很多关于android中实现MVP的文章,大家可以直接搜索学习.这些文章中,MVP的实现思路基本都是把Activity.Fragment ...

  2. android MVP框架

    原文地址:http://blog.csdn.net/guxiao1201/article/details/40147209 在开发Android应用时,相信很多同学遇到和我一样的情况,虽然项目刚开始构 ...

  3. Android MVP框架模式

    结合前一篇MVC框架模式 为了更好地细分视图(View)与模型(Model)的功能,让View专注于处理数据的可视化以及与用户的交互,同时让Model只关系数据的处理,基于MVC概念的MVP(Mode ...

  4. Android MVP框架实现登录案例

    一.Model package com.czhappy.mvpdemo.model; /** * author: chenzheng * created on: 2019/5/16 11:06 * d ...

  5. Android MVP Presenter 中引发的空指针异常

    一.概述 最近对 googlesamples/android-architecture 中的 MVP-dagger 进行了学习.对照项目的 MVP-dagger 分支,对 MVP-dagger 进行了 ...

  6. android mvp高速开发框架介绍(继续dileber)

    android mvp框架:dileber(https://github.com/dileber/dileber.git) 继续为大家介绍android mvp开源框架 dileber 官方交流qq群 ...

  7. android mvp高速开发框架介绍(dileber的简单介绍)

    今天我为大家介绍一款android mvp框架:dileber(https://github.com/dileber/dileber.git) 官方交流qq群:171443726 我个人qq:2971 ...

  8. android mvp高速开发框架介绍(dileber使用之图片下载工具)

    这几天忙着工作- 今天抽时间又把框架的bug处理了一下--并且把volley的源代码改动了一下 android mvp框架:dileber(https://github.com/dileber/dil ...

  9. android mvp高速开发框架介绍(dileber使用之小工具使用)

    android mvp框架:dileber(https://github.com/dileber/dileber.git) 继续为大家介绍android mvp开源框架 dileber 官方交流qq群 ...

  10. 【腾讯Bugly干货分享】一步一步实现Android的MVP框架

    本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/5799d7844bef22a823b3ad44 内容大纲: Android 开发 ...

随机推荐

  1. APICloud 入门教程窗口篇

    什么是窗口,窗口可以理解为一屏幕内容的一个基本载体,里面可以放导航,图片,视频,文字等组成一屏幕内容. 不同的窗口组成一个APP, 例如购物APP有[首页],[购物车],[我的]等不同的窗口.不同的窗 ...

  2. K8s 为什么会抛弃 docker

    为什么 K8s 会抛弃 docker 前言 CRI containerd 参考 为什么 K8s 会抛弃 docker 前言 在这之前先来了解下,k8s 是如何和 docker 进行交互的. CRI k ...

  3. 《Effective C++》资源管理章节

    Item 13:以对象管理资源 关键的两个想法(这种方式其实在很多地方都可以看出影子,比如managing pool的模型): 1.获得资源后立刻放入管理对象(managing object):以对象 ...

  4. UOJ60.【UR #5】怎样提高智商

    简要题意 谜题集中有 \(n\) 个谜题,第 \(i\) 个谜题形如: \(i.\) 编号小于 \(i\) 的题目中你选择了几个 \(h_i\)? A. \(a_i\) B. \(b_i\) C. \ ...

  5. 图文并茂手把手教你How to copy files or directory in nodejs npm scripts编写脚本用npm或者node命令复制文件

    每天都要开心哦~~~ 今天来个双语文档 先放出来官方文档 https://www.npmjs.com/package/copyfiles 先来说一下npm 执行的方式 1.首先,进入项目目录,下载依赖 ...

  6. 如何注册chatgpt,如何使用chatgpt,以及chatgpt无法访问的原因。chatgpt问题总结。

    chatgpt显示所在的国家地区不可用的原因. 1:chatgpt国内是不能访问的,是需要借助魔法. 一.注册过程中的问题. \1. OpenAI或ChatGPT官网打不开.这是由于ChatGPT目前 ...

  7. 一次生产环境CPU占用高的排查

    1. 项目背景 甲方是保密级别非常高的政府部门.所以我们全程拿不到任何测试数据,只能是自己模拟数据进行测试. 项目部署的时候,公司派了一人到甲方现场,在甲方客户全程监督下,进行部署,调试,导入数据等工 ...

  8. 分布式id的方案

    1 简介 在分布式系统架构中,通常会涉及到分布式全局唯一ID的生成 在复杂分布式系统中,往往需要对大量的数据和消息进行唯一标识. 如在金融.电商.支付.等产品的系统中,数据日渐增长,对数据分库分表后需 ...

  9. 有序数组的平方&长度最小的子数组&螺旋矩阵Ⅱ

    一.有序数组的平方 977.有序数组的平方 leetcode链接 1.方法概述 双"指针"解法:因为数组本来是有序的,平方后可能出现的两端大数值大的情况.所以从数组两端开始遍历,谁 ...

  10. 安装和配置Maven项目管理工具

    1.下载Maven工具包:https://maven.apache.org/download.cgi 2.解压apache-maven-3.8.4-bin.zip 3.修改apache-maven-3 ...