优势

稳定

  • 减少内存泄漏:新手很容易在线程切换的地方写出导致内存泄漏的代码,但如果把线程切换交给框架来做,出错的概率就大大降低。
  • 减少 crash:根据我的开发经历,大部分 crash 都是空指针导致的。一般线程回调里最容易出现问题,当UI销毁后,子线程依旧去操作UI,容易导致 crash。 本框架有完善的生命周期,UI销毁后,框架对子线程做了强制的停止操作,大大减少 crash 的概率。

轻量

  • 最少依赖:仅依赖 lifecycle 和 support lib.
  • 实现精简:只有几十个类

提示:这两个依赖库在 Android Studio 新建的项目里几乎都包含,也就是几乎 0 依赖。

接入成本低

  • 侵入性低:不需要修改任何现有代码
  • 无缝嵌入:可间接当做 View 使用,无论之前使用 MVP 还是 MVC,往里面加一个 View 根本不影响你的结构。

简单

  • 对原生开发友好:你几乎不需要学习框架 api 就可以开始使用。
  • 熟悉 react 和 flutter 的非常容易上手

解耦

MVVM 的强大之处在于 UI 和 逻辑 分离,处理逻辑时不需要关心 UI,写 UI 时不需要管数据从哪获取。

要更新时,你直接对数据进行修改,就会自动触发重新渲染。 并不需要担心性能问题,因为默认情况下,原来的 View 并不会被抛弃掉,仅仅会触发一次 update 操作。

public class StatefulUserWidget extends StatefulWidget<View, UserWidget> {private UserBean user = UserDataSource.getInstance().getUser();public StatefulUserWidget(Context context, Lifecycle lifecycle) {super(context, lifecycle);}@Overrideprotected State<UserWidget> createState(Context context) {return StateUtils.create(new UserWidget(context, lifecycle, user));}@Overridepublic void initWidget(UserWidget widget) {widget.setOnClickListener(v -> setState(() -> {user = UserDataSource.getInstance().getUser();}));update();}@Overridepublic void update() {super.update();widget.setUser(user);}
}

在 initWidget 方法中对 widget 设置了一个点击事件,点击后重新获取数据,自动触发 UI 的更新。 其实就是调用了 setState 方法来触发更新,类似于 react 和 flutter,更新数据的操作需要放到该方法中,否则不会触发更新。

高复用

本框架的设计思想类似于 flutter 的 "Everything's a Widget",即把所有的东西都视为控件。 各个控件之间保持独立,容器控件可以组合一个或多个控件,每个控件都有独立的生命周期。 因此,控件的复用性大大提高。

便捷的生命周期

得益于谷歌新引进的 lifecycle,让每个 widget 都可以拥有完整的生命周期,甚至数据也可以拥有生命周期。

异步支持 (同步发请求)

对于客户端编程来说,最麻烦的是各种异步调用和状态同步。 多线程编程很难,稍有不慎,轻则内存泄漏,重则直接蹦溃。 本框架内部做了处理异步请求,并在 onDestroy 时,自动取消子线程的操作,防止内存泄漏 或者 异步导致的空指针问题。

本库提供了如下方法支持数据修改,各位开发者可自行选择合适的方法。

  • setState:同步执行数据修改操作(适用于非耗时的数据修改操作,无线程切换性能消耗)
  • setStateAsync:异步执行的数据修改操作,并在UI销毁时自动停止异步线程
  • setStateAsyncWithCache:类似于 setStateAsync ,对缓存提供支持。

有了它,你可以同步的方式去发网络请求。 合并多个请求的数据变得异常轻松(比如 先请求a,在请求b,合并结果变成c)。

缓存支持

生活 缓存很难。 一千个应用有一千种缓存。 我见过网上很多缓存方案非常粗糙,大部分是直接在网络层通过拦截器来做。 因为这样不用侵入到业务代码。 但是,这样做的弊端也很大,不够灵活。 虽然像 okhttp 这样的网络库提供了对缓存的支持,比如可以设置只使用缓存,或者只使用网络,但这依然不够灵活。

如果想精准控制缓存,那就不得不自己在代码里为每一个请求都加上缓存的逻辑。 你会发现这就导致相同的缓存逻辑写了无数遍,这简直是噩梦。

不过因为本库有异步支持,所以处理缓存也变得简单多了。 至于你想怎么使用缓存,交给你自己判断吧,我们提供了一个策略接口,你只需要实现它即可。

页面状态管理

无数据页面、 错误页面、 加载中页面、 下拉刷新、 加载更多 在应用中很常见。

实现起来却不方便了,常见的做法是 BaseActivity BaseFragment,但我表示不希望看见它们,曾今我觉得 base 是很好的逻辑抽象和封装,后来发现自从有了 base,迁移和复用几乎变成了 0。 base 使得它们紧紧的耦合在一起。 如果你不明白我在说什么,我给你举个例子:

我想从项目 A 中抽出一个页面和逻辑差不多的 Activity,以便于在项目 B 中使用,这个时候最常见的就是 复制 XxxActivity.java 到 B 项目,然后后面你懂的。

但本库对这几种页面状态提供了高度的封装,你不必再依赖于 Base。 不仅仅是 activity,甚至一个 button,你都可以让他拥有如上的这几种状态。

请求过滤

不知道你是否烦恼过,产品跟你说,用户可能狂按按钮,让你加个判断,减少不必要的请求。 听起来需求很简单,防止重复点击就行,但可达鸭眉头一皱,发现事情并不简单。 一个按钮防重复点击也就几行代码,但几十个几百个按钮呢? 你说可以抽出一个 BaseButton? 那点击的如果是个 text 或 fab 这样的控件呢? 确实 base 可以解决很多重复代码,但相应的你要把对应的控件全部换成 base,工作量也很大。

本库贴心的为大家提供了请求过滤器,默认就过滤重复的请求,虽然不是在 UI 上过滤,但同一个 task 的请求是不会重复执行的,这点可以放心。 如果你有其他过滤需求,还可以自定义实现一个过滤器。

重试支持

请求失败重试也是很常见的需求,但实现并不简单,基本有2种做法:

  • 如果在代码层面做,就需要在请求失败的回调里重新发起一次,还要记录次数,很是麻烦。
  • 如果在网络层做,你就得对网络层进行一次封装,提供一个方法设置重试次数。 然而,这种方法弊端很大,不能和业务很好的联系。 因为网络层并不知道什么时候应该重试,网络请求失败就重试? 还是返回内容里面标识不成功就重试呢?

本库同样提供了重试支持,因为有了异步支持,重试对框架来说,就是一个循环,然而这个循环框架都帮你写好了,你只需告诉框架重试次数和什么时候应该重试就可以了。

动态属性设置能力

动态换肤或样式修改也是一个很常见的需求,然而为了实现这样的需求,往往需要开发者在代码里提前写好根据配置修改的UI的代码。

本库同样提供了支持,你可以通过一个 json 来对 wiget 进行属性修改。 所以换个皮肤或改个样式都是分分钟的事啦。

单页面应用(测试)

搞前端的应该很清楚这是什么,就是所有渲染都是在一个页面上展示,页面跳转都是通过前端路由来控制。 对应到客户端,就是所有 UI 都在一个 activity 中展示。

这样做有什么意义? 安卓插件化最大的问题是四大组件需要提前在 manifest 中注册,虽然目前有一些开源项目通过底层 hook 方式解决了这个问题,但是以后的安卓版本就不清楚会不会把这个限制了。 而且目前的插件化都需要对资源进行合并,这就使得成功率下降。

如果是单页面应用,动态下发字节码执行也变得有可能。 而且这样成功率理论上接近 100%。 打算有时间尝试一下。

我的意思就是像前端那样具有随时更新的能力,不知道会不会被封杀,逃。。。

快速开始

引入库

【可选】 添加 java8 支持

android {
...compileOptions {sourceCompatibility JavaVersion.VERSION_1_8targetCompatibility JavaVersion.VERSION_1_8}
...
}

添加 maven 仓库

allprojects {repositories {...maven { url 'https://jitpack.io' }}
}

添加依赖

def support_version = '28.0.0'
def lifecycle_version = '1.1.1'implementation 'com.github.ittianyu:relight:0.1.0'
implementation "com.android.support:appcompat-v7:$support_version"
implementation "com.android.support:design:$support_version"// Support library depends on this lightweight import
implementation "android.arch.lifecycle:runtime:$lifecycle_version"

如果开启了 java8

// alternately - if using Java8, use the following instead of compiler
implementation "android.arch.lifecycle:common-java8:$lifecycle_version"

混淆

使用了 xml 支持,必须加入混淆,未使用的可以不加。

-keep class * extends com.ittianyu.relight.widget.Widget {*;}

小结;

后面会写一篇mvvp框架实战,以及它的具体使用。也欢迎大家加入Android进阶交流群;964557053。进群可免费领取一份最新技术大纲和Android进阶资料。请备注csdn

还在用 MVP?快来试试 MVVM框架吧! 1相关推荐

  1. 还在用 MVP?快来试试 MVVM框架吧!

    优势 稳定 减少内存泄漏:新手很容易在线程切换的地方写出导致内存泄漏的代码,但如果把线程切换交给框架来做,出错的概率就大大降低. 减少 crash:根据我的开发经历,大部分 crash 都是空指针导致 ...

  2. android mvp mvvm ppt,还在用 MVP?快来试试 MVVM! Relight:轻量级 MVVM 框架

    优势 稳定 减少内存泄漏:新手很容易在线程切换的地方写出导致内存泄漏的代码,但如果把线程切换交给框架来做,出错的概率就大大降低. 减少 crash:根据我的开发经历,大部分 crash 都是空指针导致 ...

  3. ❤️你还在用visio画图吗?已经落伍啦!快来试试轻量级绘图神器draw.io吧!❤️

    引子 最近写模块文档,需要绘制一些程序流程示意图,之前一直用word+visio的组合,但是现在都是typora+xmind的轻组合了,所以这次也尝试了一个新的轻量级绘图工具draw.io.文末附上在 ...

  4. 结合vue、react、angular谈谈MVC、MVP、MVVM框架

    首先,在谈这个话题之前, 我们有必要了解一下库和框架的区别. 我们先来看react官网以及vue官网对他们的定位: react: vue: react我们不说了,官网上明明白白说了,人家是一个libr ...

  5. 只会用console.log调试?快来试试这些高效的调试方法

    别光知道用console.log调试了,快来试试这些高效的调试方法! 作为一名前端开发人员,你一定经常是用 console.log 来进行开发调试,这当然没什么问题,但你可能不知道,除了 consol ...

  6. 检测图片篡改困难?快来试试这款黑科技

    一.前言 之前看到过一个新闻:上海一对硕士夫妻PS篡改结婚证.离婚证,竟真的骗保成功了: 当时看到这个新闻时我是惊讶又有点惶恐的,惊讶于真有这么胆子大的人,惶恐于最近我们刚好有需要去做一些证件图片是否 ...

  7. linux系统运行flash3d,在Linux上运行STM32,快来试试!

    原标题:在Linux上运行STM32,快来试试! STM32MP1多核微处理器,带有650Mhz主频的cortex-A7双核以及一个主频为209Mhz的cortex-M4核,即片内拥有三核.很多STM ...

  8. MVC、MVP、MVI、MVVM 和 VIPER 设计模式

    "在过去的几年里,出现了几种新的模式,所有这些都使开发人员的生活变得前所未有的轻松.通过分离代码库的某些部分,这些模式中的每一个都试图使代码更具可读性,更易于测试,并最终更易于维护" ...

  9. 快来试试Python写的游戏《我的世界》

    <我的世界 Minecraft>大家应该都听说过,但你有没有想过自己用Python写一个这样的游戏呢?太难.太复杂了?也许吧,但是不试一试你怎么知道能不能成呢? 国外有位叫fogleman ...

最新文章

  1. MAP/CAP信令常见消息
  2. iOS开发之解决隐藏tabbar后原位置无法响应点击事件的问题
  3. group by+having查询
  4. 一天1个机器学习知识点(三)
  5. Java文件流应用:剪切文件
  6. pg加密扩展的安装_postgresql的加密扩展插件pgcrypto
  7. java郝斌_郝斌Java自学教程全集打包
  8. ip地址能够什么标识网络中的一台计算机,计算机网络第一学期期末考试模拟练习题(这套卷子上面也会有原题).pdf...
  9. 前端培训什么机构好?有什么好的学习方法能少走弯路?
  10. python程序设计实践教程答案江苏_《Python程序设计》习题与答案python教材答案
  11. Fredholm第二类积分方程的MATLAB代码实现(1)
  12. php form标签中的属性,form标签中的属性详解
  13. 什么是 yum?更改yum源 yum的相关命令
  14. 小暑 |入伏前,这样做,宝宝长高高更聪明!
  15. 游戏‘微信打飞机’ 第三课
  16. android 照片拼接长图_长图拼接app下载 长图拼接制作 for Android v2.6.1 安卓版 下载-脚本之家...
  17. Java 提供给第三方使用接口方法
  18. Getting in Shape
  19. flexf布局中的flex-grow和flex-shrink的计算方法,flex简写的规则
  20. 黄陈晨,你可以陪着我么

热门文章

  1. 看门狗2服务器连接中断,看门狗2无法连接服务器 | 手游网游页游攻略大全
  2. 2021了React Native热更新怎么搞(react-native-code-push,Android,iOS)
  3. 免费教微商怎么引流,免费教你微信主动加你
  4. 基础英语语法笔记(全)
  5. Spring——入门
  6. 使用公共 Registry - 每天5分钟玩转 Docker 容器技术(19)
  7. android向手机发送信息,魅蓝note短信怎么发送?短信发送使用小技巧介绍
  8. CSGO系统拆解学习
  9. 中级职称英语计算机面试,职称英语面试的一些要求
  10. JS 中的类数组对象如何转换为数组?