Android MVP框架 详细代码
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框架 详细代码的更多相关文章
- 如何实现自己的Android MVP框架?
相信熟悉android开发的童鞋对MVP框架应该都不陌生吧,网上很多关于android中实现MVP的文章,大家可以直接搜索学习.这些文章中,MVP的实现思路基本都是把Activity.Fragment ...
- android MVP框架
原文地址:http://blog.csdn.net/guxiao1201/article/details/40147209 在开发Android应用时,相信很多同学遇到和我一样的情况,虽然项目刚开始构 ...
- Android MVP框架模式
结合前一篇MVC框架模式 为了更好地细分视图(View)与模型(Model)的功能,让View专注于处理数据的可视化以及与用户的交互,同时让Model只关系数据的处理,基于MVC概念的MVP(Mode ...
- Android MVP框架实现登录案例
一.Model package com.czhappy.mvpdemo.model; /** * author: chenzheng * created on: 2019/5/16 11:06 * d ...
- Android MVP Presenter 中引发的空指针异常
一.概述 最近对 googlesamples/android-architecture 中的 MVP-dagger 进行了学习.对照项目的 MVP-dagger 分支,对 MVP-dagger 进行了 ...
- android mvp高速开发框架介绍(继续dileber)
android mvp框架:dileber(https://github.com/dileber/dileber.git) 继续为大家介绍android mvp开源框架 dileber 官方交流qq群 ...
- android mvp高速开发框架介绍(dileber的简单介绍)
今天我为大家介绍一款android mvp框架:dileber(https://github.com/dileber/dileber.git) 官方交流qq群:171443726 我个人qq:2971 ...
- android mvp高速开发框架介绍(dileber使用之图片下载工具)
这几天忙着工作- 今天抽时间又把框架的bug处理了一下--并且把volley的源代码改动了一下 android mvp框架:dileber(https://github.com/dileber/dil ...
- android mvp高速开发框架介绍(dileber使用之小工具使用)
android mvp框架:dileber(https://github.com/dileber/dileber.git) 继续为大家介绍android mvp开源框架 dileber 官方交流qq群 ...
- 【腾讯Bugly干货分享】一步一步实现Android的MVP框架
本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/5799d7844bef22a823b3ad44 内容大纲: Android 开发 ...
随机推荐
- 为什么NoSQL数据库这么受欢迎?
大数据时代,NoSQL数据库是企业构建数据能力的核心工具之一.近期,在2022腾讯全球数字生态大会NoSQL数据库专场上,腾讯云发布了多项NoSQL产品能力升级,并重点讲解了其背后的自研技术要点及实现 ...
- 使用Git提交代码
目录 1.提交前准备工作 2.代码提交步骤 3.从git上面拉代码 4.Git变更集 5.参考资料 1.提交前准备工作 首先去git官网下载git工具(Git GUI Here.Git Bash He ...
- [生命科学] 生物基础实验之PCR验证
生物基础实验之PCR验证 文章目录 生物基础实验之PCR验证 实验步骤一 实验步骤二 实验步骤三 配胶 实验步骤四 电泳 实验步骤五 跑胶 实验步骤一 在离心管加入7.5μL Master Mix 溶 ...
- P7914 [CSP-S 2021] 括号序列
简要题意 给定 \(k\),定义 "超级括号序列"(简称括号序列,下同) 字符串为: 仅由 ( ) * 三种字符组成. 下面令 \(S\) 为不超过 \(k\) 个 \(\ast\ ...
- 如何实现在react现有项目中嵌入Blazor?
如何实现在react现有项目中嵌入Blazor? 目前官方只提供了angular和react俩种示例所以本教程只将react教程 思路讲解: 首先在现有react项目中我们可能某些组件是在Blazor ...
- 对象的反序列化流_ObjectInputStream类
对象的反序列化流_ObjectInputStream类 ObjectInputStream反序列化流,将之前使用ObjectOutputStream序列化的原始数据恢复为对象. 构造方法 public ...
- centos7连接WIFI
centos7图形化界面可以直接连接WIFI,命令行会稍麻烦一些 环境: 1.笔记本安装centos7,没有很大的流量,基本都是交互 2.桌子后面的线路太乱,想要省去一根网线 过程: 1.安装软件 y ...
- 【随笔记】FRAM 铁电随机存储器(MB85RC04VPNF)
参考资料 器件规格书:https://atta.szlcsc.com/upload/public/pdf/source/20131104/1457706659695.pdf I2C总线规范:https ...
- 明解STM32—GPIO理论基础知识篇之基本结构
一.前言 万物皆有源头,大家学习单片机的源头操作就是通过GPIO口点灯,GPIO作为STM32最基础的外设,也是大家最先接触的外设.当然,看似基础的GPIO,不仅仅是简单的设置好IO口,让灯亮起就 ...
- elasticsearch之使用正则表达式自定义分词逻辑
一.Pattern Analyzer简介 elasticsearch在索引和搜索之前都需要对输入的文本进行分词,elasticsearch提供的pattern analyzer使得我们可以通过正则表达 ...