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. int类型bit都满了之后继续累加

    uint8_t的最大值是255,如果再加1那低8位都是0,最后结果也是0 #include<stdio.h> #define uint8_t unsigned char int main( ...

  2. 15、MySQLTransactionRollbackException: Lock wait timeout exceeded; try restarting transaction

    转载自 一.报错信息: Error updating database. Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollback ...

  3. Linux基础:ssh与scp

    登陆 登陆服务器 ssh user@hostname user: 用户名 hostname :IP地址或域名 第一次登陆会提示 The authenticity of host '123.57.47. ...

  4. 【Dubbo3终极特性】「流量治理体系」一文教你如何通过Dubbo-Admin实现动态进行流量隔离机制

    背景信息 如果一个应用有多个版本在线上同时运行,部署在不同环境中,如日常环境和特殊环境,则 可以使用标签路由对不同环境中的不同版本进行流量隔离,将秒杀订单流量或不同渠道订单流量路由到特殊环境,将正常的 ...

  5. 12.ThreadLocal的那点小秘密

    大家好,我是王有志.关注王有志,一起聊技术,聊游戏,聊在外漂泊的生活. 好久不见,不知道大家新年过得怎么样?有没有痛痛快快得放松?是不是还能收到很多压岁钱?好了,话不多说,我们开始今天的主题:Thre ...

  6. Vue3 企业级优雅实战 - 组件库框架 - 11 组件库的打包构建和发布

    回顾第一篇文章中谈到的组件库的几个方面,只剩下最后的.也是最重要的组件库的打包构建.本地发布.远程发布了. 1 组件库构建 组件库的入口是 packages/yyg-demo-ui,构建组件库有两个步 ...

  7. 从 Newtonsoft.Json 迁移到 System.Text.Json

    一.写在前面 System.Text.Json 是 .NET Core 3 及以上版本内置的 Json 序列化组件,刚推出的时候经常看到踩各种坑的吐槽,现在经过几个版本的迭代优化,提升了易用性,修复了 ...

  8. 面试必问:JVM 如何确定死亡对象?

    在 JVM 中,有两个非常重要的知识点,一个是 JVM 的内存布局(JVM 运行时的数据区域),另一个就是垃圾回收.而垃圾回收中又有两个重要的知识点,一个是如何确定 JVM 中的垃圾对象,另一个是使用 ...

  9. SPI的 CLK_POL和CLK_PHA

    1.模式0(CPOL=0,CPHA=0) 模式0特性: CPOL = 0:空闲时是低电平,第1个跳变沿是上升沿,第2个跳变沿是下降沿 CPHA = 0:数据在第1个跳变沿(上升沿)采样 2.模式1(C ...

  10. H3C MS4300V2配置mac地址与接口绑定

    配置mac地址与接口绑定 例: <h3c>system-view     //进入系统视图 [h3c]int g 1/0/45 //进入45接口 [h3c-GigabitEthernet1 ...