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. [R语言] 基于R语言实现树形图的绘制

    树状图(或树形图)是一种网络结构.它由一个根节点组成,根节点产生由边或分支连接的多个节点.层次结构的最后一个节点称为叶.本文主要基于R语言实现树形图的绘制.关于python实现树形图的绘制见:基于ma ...

  2. BBS升级版

    BBS项目 项目的前期准备 1.django2.2 创建一个django目录 (需要配置环境变量和数据库) 'DIRS': [os.path.join(BASE_DIR, 'templates'), ...

  3. SQL29 计算用户的平均次日留存率

    SQL29 计算用户的平均次日留存率 困难 通过率:48.58% 时间限制:1秒 空间限制:256M 描述 题目:现在运营想要查看用户在某天刷题后第二天还会再来刷题的平均概率.请你取出相应数据. 示例 ...

  4. 目标检测+双目测距——基于yolov5

    效果 测试例子1 输入: 左图 右图 输出: 测试例子2 输入: 左图 右图 输出: 测试例子3 输入: 左图 右图 输出: 核心代码 基于yolov5-6.1版本和双目测距+点云--使用Middle ...

  5. py之循环,函数

    循环 a=1 while a<10: print(a) a+=1 a=[123,1235,123124,1231] while a: a1=a.pop() print(a1) for a1 in ...

  6. Java基础学习笔记-类的静态属性和静态方法--待继续补充

    程序运行时的内存占用 代码区(code area) 存放代码 数据区(data area) 存放全局数据.静态数据 堆区(heap area) 存放动态申请的数据 栈区(stack area) 存放局 ...

  7. Sundial (二)

    相关重要的组件一览 Triggers(触发器)相关类 保存触发器相关参数,例如起止时间,次数,间隔时间等,其中Sundial支持多种类型触发器 多种类型的触发器必须重写GetNextOccurrenc ...

  8. 12月19日内容总结——Q查询进阶、ORM查询优化、ORM事务、ORM常用字段类型和字段参数、Ajax介绍、数据编码格式、Ajax携带文件数据

    目录 一.Q查询进阶操作 二.ORM查询优化 三.ORM事务操作 四.ORM常用字段类型 五.ORM常用字段参数 六.Ajax AJAX简介 应用场景 AJAX的优点 语法实现 七.数据编码格式(Co ...

  9. hashlib加密、subprocess、logging日志模块

    1.hashlib加密模块 1.加密:将明文数据处理成密文数据,让人无法看懂 2.为什么加密:保证数据的安全 3.如何判断数据是否加密:如果是一长串没有规律的字符串(数字.字母.符号)那么数据被加密 ...

  10. 元数据库 information_schema.tables

    转  https://www.cnblogs.com/ssslinppp/p/6178636.html 1.information_schema数据库 对于mysql和Infobright等数据库,i ...