双叒叕-一个-Android-MVVM-组件化架构框架?

  • Lifecycle
  • ViewModel
  • LiveData
  • ViewBinding
  • Android KTX
  • OkHttp:网络请求
  • Retrofit:网络请求
  • MMKV:腾讯基于 mmap 内存映射的 key-value 本地存储组件
  • Glide:快速高效的Android图片加载库
  • ARoute:阿里用于帮助 Android App 进行组件化改造的框架 —— 支持模块间的路由、通信、解耦
  • BaseRecyclerViewAdapterHelper:一个强大并且灵活的RecyclerViewAdapter
  • StatusBarUtil:状态栏
  • EventBus:适用于Android和Java的发布/订阅事件总线
  • Bugly:腾讯异常上报及热更新(只集成了异常上报)
  • PermissionX:郭霖权限请求框架
  • Chuck:适用于Android OkHttp 客户端的应用内HTTP拦截器 显示请求信息
  • LeakCanary:Android的内存泄漏检测库

使用方式

  • 1.下载本项目删除无用的文件
  • 2.修改项目包名及各组件包结构,修改 AppName
  • 3.填写自己的 Bugly key 在 BaseApplication initialize() 方法中
  • 这样就可以使用了,当然可以删除不用的第三方,或者添加相应要使用的第三方,具体规范看下面的框架解读

Demo

  • 项目里有一个demo分支,这是我写的一个小例子,可以结合Demo去熟悉这个框架

框架解读

组件化相关

  • 本框架采用的是组件化架构,核心组件就是 Base 和 Common ,这两个组件都属于公共组件,负责为功能业务组件提供支持
  • Base 组件主要集成了各种需要使用的第三方库和依赖或者公用的 aar/jar,并将依赖向依赖该组件的组件传递,需要集成的依赖,全部集成在 Base 组件内,Base 组件也提供了各种基类封装以及工具类、扩展函数、顶层函数,这些都应该是项目无关性的,可以达到 Base 模块直接拷贝复用的效果
  • Common 组件主要是与项目有关的公用库,比如网络接口,全局常量, bean 类等,和项目有关的东西因该放在 Common 组件内,不要侵入 Base 组件,因为和项目有关的东西一旦放在了 Base 组件内,想要直接拷贝复用 Base 组件就不可能了,肯定会有一堆和项目相关的东西,项目的资源文件或者公用的资源文件最好统一放在 Common 组件内,方便公用,方便管理
  • Base 和 Common 都属于公共组件,区别就在于 Base 比 Common 更底层,偏于与项目无关性,而 Common 是与项目有关性
  • 项目的依赖版本管理和项目参数等配置统一写在了 buildSrc 文件夹内,内部维护了几个 kt 文件进行对依赖库版本及项目参数统一存放管理
  • 功能组件应该依赖 Common 组件,壳 App 依赖所有的功能组件,要尽量避免各组件互相依赖,壳 App 内不要写东西,只当一个壳负责集成各个组件,每个组件都应该在 build.gradle 文件内设置资源命名规范,目的是为了避免资源冲突

android {
resourcePrefix “资源名前缀”
}
复制代码

  • 各个功能业务组件可以单独运行,通过 buildSrc/BuildConfig.kt 中的 isAppMode 参数控制,项目业务复杂起来后,就需要为每个组件单独编写供其正常单独运行的逻辑代码

MVVM相关

  • MVVM 采用 Jetpack 组件 + Repository 设计模式 实现,所使用的 Jetpack 并不是很多,像 DataBinding、Hilt(不支持多模块)、Room 等并没有使用,如果需要可以添加。采用架构模式目的就是为了解偶代码,对代码进行分层,各模块各司其职,所以既然使用了架构模式那就要遵守好规范
  • Repository 仓库层负责数据的提供,ViewModel 无需关心数据的来源,Repository 内避免使用 LiveData,框架里使用了 Kotlin 协程的 Flow 进行处理请求或访问数据库,最后将数据发射到 ViewModel 调用者,Flow上游负责提供数据,下游也就是ViewModel获取到数据使用LiveData进行存储,View层订阅LiveData,实现数据驱动视图
  • 三者的依赖都是单向依赖,View -> ViewModel -> Repository

示例代码及注意事项🐽

ViewModel

ViewModel 类旨在以注重生命周期的方式存储和管理界面相关的数据。ViewModel 类让数据可在发生屏幕旋转等配置更改后继续留存。
使用方式:

class MainViewModel : ViewModel(){
}

class MainActivity : AppCompatActivity() {
// 获取无参构造的ViewModel实例
val mViewModel = ViewModelProvider(this).get(MainViewModel::class.java)
}
复制代码

资料:
官方文档: developer.android.com/topic/libra…
Android ViewModel,再学不会你砍我: juejin.im/post/684490…

LiveData

LiveData是一种可观察的数据存储器类。与常规的可观察类不同,LiveData 具有生命周期感知能力,意指它遵循其他应用组件(如 ActivityFragment 或 Service)的生命周期。这种感知能力可确保 LiveData 仅更新处于活跃生命周期状态的应用组件观察者
LiveData 分为可变值的MutableLiveData和不可变值的LiveData
常用方法:

fun test() {
val liveData = MutableLiveData()
// 设置更新数据源
liveData.value = “LiveData”
// 将任务发布到主线程以设置给定值
liveData.postValue(“LiveData”)
// 获取值
val value = liveData.value
// 观察数据源更改(第一个参数应是owner:LifecycleOwner 比如实现了LifecycleOwner接口的Activity)
liveData.observe(this, {
// 数据源更改后触发的逻辑
})
}
复制代码

资料:
官方文档: developer.android.com/topic/libra…

Lifecycle

Lifecycle 是一个类,用于存储有关组件(如 Activity 或 Fragment)的生命周期状态的信息,并允许其他对象观察此状态。
LifecycleOwner 是单一方法接口,表示类具有 Lifecycle。它具有一种方法(即 getLifecycle()),该方法必须由类实现。
实现 LifecycleObserver 的组件可与实现 LifecycleOwner 的组件无缝协同工作,因为所有者可以提供生命周期,而观察者可以注册以观察生命周期。

资料:
官方文档: developer.android.com/topic/libra…

ViewBinding

通过视图绑定功能,您可以更轻松地编写可与视图交互的代码。在模块中启用视图绑定之后,系统会为该模块中的每个 XML 布局文件生成一个绑定类。绑定类的实例包含对在相应布局中具有 ID 的所有视图的直接引用。
在大多数情况下,视图绑定会替代 findViewById
使用方式:
按模块启用ViewBinding

// 模块下的build.gradle文件
android {
// 开启ViewBinding
// 高版本AS
buildFeatures {
viewBinding = true
}
// 低版本AS 最低3.6
viewBinding {
enabled = true
}
}
复制代码

Activity 中 ViewBinding 的使用

// 之前设置视图的方法
setContentView(R.layout.activity_main)

// 使用ViewBinding后的方法
val mBinding = ActivityMainBinding.inflate(layoutInflater)
setContentView(mBinding.root)

// ActivityMainBinding类是根据布局自动生成的 如果没有请先build一下项目
// ViewBinding会将控件id转换为小驼峰命名法,所以为了保持一致规范,在xml里声明id时也请使用小驼峰命名法
// 比如你有一个id为mText的控件,可以这样使用
mBinding.mText.te​
xt = “ViewBinding”
复制代码

Fragment 中 ViewBinding 的使用

// 原来的写法
return inflater.inflate(R.layout.fragment_blank, container, false)

// 使用ViewBinding的写法
mBinding = FragmentBlankBinding.inflate(inflater)
return mBinding.root
复制代码

资料:
官方文档: developer.android.com/topic/libra…
CSDN: blog.csdn.net/u010976213/…

ARoute

ARoute是阿里巴巴的一个用于帮助 Android App 进行组件化改造的框架 —— 支持模块间的路由、通信、解耦
使用方式:

// 1.在需要进行路由跳转的Activity或Fragment上添加 @Route 注解
@Route(path = “/test/activity”)
public class YourActivity extend Activity {

}

// 2.发起路由跳转
ARouter.getInstance()
.build(“目标路由地址”)
.navigation()

// 3.携带参数跳转
ARouter.getInstance()
.build(“目标路由地址”)
.withLong(“key1”, 666L)
.withString(“key3”, “888”)
.withObject(“key4”, new Test(“Jack”, “Rose”))
.navigation()

// 4.接收参数
@Route(path = RouteUrl.MainActivity2)
class MainActivity : AppCompatActivity() {

// 通过name来映射URL中的不同参数
@Autowired(name = “key”)
lateinit var name: String

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(mBinding.root)
// ARouter 依赖注入 ARouter会自动对字段进行赋值,无需主动获取
ARouter.getInstance().inject(this)
}
}

// 5.获取Fragment
Fragment fragment = (Fragment) ARouter.getInstance().build(“/test/fragment”).navigation();
复制代码

资料:
官方文档:github.com/alibaba/ARo…

屏幕适配 AndroidAutoSize

屏幕适配使用的是 JessYan 大佬的 今日头条屏幕适配方案终极版
GitHub: github.com/JessYanCodi…
使用方式:

// 在清单文件中声明


// 主单位使用dp 没设置副单位



// 默认是以竖屏的宽度为基准进行适配
// 如果是横屏项目要适配Pad(Pad适配尽量使用两套布局 因为手机和Pad屏幕宽比差距很大 无法完美适配)


// 以高度为基准进行适配 (还需要手动代码设置以高度为基准进行适配) 目前以高度适配比宽度为基准适配 效果要好


// 在Application 中设置
// 屏幕适配 AndroidAutoSize 以横屏高度为基准进行适配
AutoSizeConfig.getInstance().isBaseOnWidth = false
复制代码

EventBus APT

事件总线这里选择的还是EventBus,也有很多比较新的事件总线框架,还是选择了这个直接上手的 在框架内我对EventBus进行了基类封装,自动注册和解除注册,在需要注册的类上添加@EventBusRegister注解即可,无需关心内存泄漏及没及时解除注册的情况,基类里已经做了处理

@EventBusRegister
class MainActivity : AppCompatActivity() {
}
复制代码

很多使用EventBus的其实都没有发现APT的功能,这是EventBus3.0的重大更新,使用EventBus APT可以编译期生成订阅类,这样就可以避免使用低效率的反射,很多人不知道这个更新,用着3.0的版本,实际上却是2.0的效率 项目中已经在各模块中开启了EventBus APT,EventBus会在编译器对各模块生成订阅类,需要我们手动代码去集成这些订阅类

// 因为App包依赖了所有的模块所以选择在App包下的Application中进行设置
// 开启EventBus APT
EventBus
.builder()
.addIndex(“各模块生成的订阅类的实例 类名在 moduleBase.gradle 脚本中进行了设置 比如 Lib_Main 生成的订阅类就是 MainEventIndex”)
.installDefaultEventBus()
复制代码

PermissionX

PermissionX 是郭霖的一个权限申请框架
使用方式:

PermissionX.init(this)
.permissions(“需要申请的权限”)
.request { allGranted, grantedList, deniedList -> }
复制代码

最后

小编这些年深知大多数初中级Android工程师,想要提升自己,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助

因此我收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人

都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

资料⬅专栏获取

小编这些年深知大多数初中级Android工程师,想要提升自己,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助

因此我收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。

[外链图片转存中…(img-takktOGA-1719099514376)]一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人

都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

资料⬅专栏获取

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/32442.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【学习笔记】CSS

CSS 1、 基础篇 1.1、选择器 1.2、长度单位 1.3、CSS2 常用属性 1.4、盒模型 1.5、浮动 1.6、定位 position2、 CSS3 2.1、新增长度单位 2.2、新增颜色表示 2.3、新增选择器 2.4、新增盒子属性 2.5、新增背景属性 …

STM32单片机BKP备份寄存器和RTC实时时钟详解

文章目录 1. Unix时间戳 2. UTC/GMT 3. 时间戳转换 4. BKP简介 5. BKP基本结构 6. RTC简介 7. RTC框架图 8. RTC基本结构 9. 代码示例 1. Unix时间戳 实时时钟,本质上是一个定时器,专门用来产生年月日时分秒。 Unix 时间戳(Unix T…

CausalMMM:基于因果结构学习的营销组合建模

1. 摘要 在线广告中,营销组合建模(Marketing Mix Modeling,MMM) 被用于预测广告商家的总商品交易量(GMV),并帮助决策者调整各种广告渠道的预算分配。传统的基于回归技术的MMM方法在复杂营销场景…

Windows10中端口被占用处理方法

前言 在Windows 10中,查看端口被占用情况的方法主要依赖于命令行工具netstat。以下是详细步骤,以及必要的解释和归纳: 打开命令提示符 方法1:使用快捷键Win R,打开“运行”对话框,输入cmd,然…

大疆炸机后MOV修复方法(DJI Inspire 3)

dji大疆可以说是无人机中的华为,产品线之广性能之高让高傲的美国人侧面,质量和性价比才是王道。另外产品线的细分也是制胜法宝,无论是手持、农用机、特殊无人机还是影视级产品DJI都有涉及,给人的感觉就是在无人机细分方面它已经无…

java泛型学习

没有java泛型会存在的问题 假设我们有一个方法,希望通过传递不同类型的参数,输出不同类型的对象值。正常情况下我们可能会写不同的方法来实现,但是这样会导致类不断增加,并且类方法很相似,不能够复用。进而导致类爆炸…

基于顺序存储的环形队列算法库构建

学习贺利坚老师基于数组的环形队列 数据结构之自建算法库——顺序环形队列_下空队列q中依次入队列数据元素abc-CSDN博客文章浏览阅读5.2k次,点赞6次,收藏6次。本文针对数据结构基础系列网络课程(3):栈和队列中第9课时环形队列的存储及基本操…

华为---理解OSPF Route-ID(五)

9.5 理解OSPF Route-ID 9.5.1 原理概述 一些动态路由协议要求使用Router-ID作为路由器的身份标示,如果在启动这些路由协议时没有指定Router-ID,则默认使用路由器全局下的路由管理Router-ID。 Router-ID选举规则为,如果通过Router-ID命令配置了Router-…

1.22 LeetCode总结(基本算法)_位运算

进制的概念 进制即进位计数制,是利用固定的数字符号和统一的规则的带进位的计数方法。 任何一种进位计数制都有一个基数,基数为 X 的进位计数制称为 X 进制,表示每一个数位上的数运算时都是逢 X 进一。 504. 七进制数 手法1:当…

APP启动流程解析

简单概括启动微信的流程就是: 1.Launcher通知AMS 要启动微信了,并且告诉AMS要启动的是哪个页面也就是首页是哪个页面 2.AMS收到消息告诉Launcher知道了,并且把要启动的页面记下来 3.Launcher进入Paused状态,告诉AMS&#xff0c…

[FreeRTOS 基础知识] 互斥访问与回环队列 概念

文章目录 为什么需要互斥访问?使用队列实现互斥访问休眠和唤醒机制环形缓冲区 为什么需要互斥访问? 在裸机中,假设有两个函数(func_A, func_B)都要修改a的值(a),那么将a定义为全局变…

css-vxe列表中ant进度条与百分比

1.vxe列表 ant进度条 <vxe-column field"actualProgress" title"进度" align"center" width"200"><template #default"{ row }"><a-progress:percent"Math.floor(row.actualProgress)"size"s…

Java程序之可爱的小兔兔

题目&#xff1a; 古典问题&#xff0c;有一对兔子&#xff0c;从出生后第3个月起每个月都生一对兔子&#xff0c;小兔子长到第三个月后每个月又生一对兔子&#xff0c;假如兔子都不死&#xff0c;问每个月的兔子总数为多少? 程序分析&#xff1a; 兔子的规律为数列1,1,2,3,…

C++基础知识——《缺省参数》和《函数重载》

P. S.&#xff1a;以下代码均在VS2019环境下测试&#xff0c;不代表所有编译器均可通过。 P. S.&#xff1a;测试代码均未展示头文件stdio.h的声明&#xff0c;使用时请自行添加。 博主主页&#xff1a;Yan. yan.                        …

【Android进阶学习】Android-广播接收器(Broadcast-Receivers)

android:theme“style/AppTheme” > 现在&#xff0c;无论什么时候Android设备被启动&#xff0c;都将被广播接收器MyReceiver所拦截&#xff0c;并且在onReceive()中实现的逻辑将被执行。 有许多系统产生的事件被定义为类Intent中的静态常量值。下面的表格列举了重要的系…

微积分-导数1(导数与变化率)

切线 要求与曲线 C C C相切于 P ( a , f ( a ) ) P(a, f(a)) P(a,f(a))点的切线&#xff0c;我们可以在曲线上找到与之相近的一点 Q ( x , f ( x ) ) Q(x, f(x)) Q(x,f(x))&#xff0c;然后求出割线 P Q PQ PQ的斜率&#xff1a; m P Q f ( x ) − f ( a ) x − a m_{PQ} \…

AES 高级加密加速器实验

1、AES介绍 Kendryte K210 内置 AES&#xff08;高级加密加速器&#xff09;&#xff0c;相对于软件可以极⼤的提高 AES 运算速度。 AES 加速器支持多种加密/解密模式&#xff08;ECB,CBC,GCM&#xff09;,多种⻓度的 KEY&#xff08;ECB,CBC,GCM&#xff09;的运算。 AES 加…

Linux常用环境变量

Linux常用环境变量 一、常用的默认的shell环境变量二、环境变量 PATH三、持久化修改环境变量四、常用的环境变量 一、常用的默认的shell环境变量 1、当我们在shell命令行属于一个命令&#xff0c;shell解释器去解释这个命令的时候&#xff0c;需要先找到这个命令. 找到命令有两…

鸿蒙 HarmonyOS NEXT星河版APP应用开发—上篇

一、鸿蒙开发环境搭建 DevEco Studio安装 下载 访问官网&#xff1a;https://developer.huawei.com/consumer/cn/deveco-studio/选择操作系统版本后并注册登录华为账号既可下载安装包 安装 建议&#xff1a;软件和依赖安装目录不要使用中文字符软件安装包下载完成后&#xff0…

【Linux 基础】文件与目录管理

1. 文件和目录的基本概念 文件&#xff1a;是数据的集合&#xff0c;可以是文本、图像、视频等。 目录&#xff08;也称为文件夹&#xff09;&#xff1a;是文件和子目录的集合&#xff0c;用于组织文件。 2. 目录和路径 绝对路径&#xff1a;从根目录&#xff08;/&#x…