# CloudMusic **Repository Path**: gsphelow/cloud-music ## Basic Information - **Project Name**: CloudMusic - **Description**: No description available - **Primary Language**: Kotlin - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 11 - **Forks**: 1 - **Created**: 2021-12-15 - **Last Updated**: 2025-11-11 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # NatureHero #### 介绍 android、Kotlin 、JetPack、MVVM、XUI [感谢] (https://blog.csdn.net/Moriafly/article/details/113351949) [感谢] (https://github.com/Moriafly/DsoMusic/blob/master/app/src/main/java/com/dirror/music/ui/player/PlayerActivity.kt) [感谢] (https://blog.csdn.net/qq_33238562/article/details/104755077) #### 软件架构 - Jetpack中的许多架构组件是专门为了MVVM架构而量身打造的。 - MVVM(Model-View-ViewModel)是一种高级项目架构模式,目前已被广泛应用在Android程序设计领域,类似的架构模式还有MVP、MVC等。简单来讲,MVVM架构可以将程序结构主要分成3部分:Model是数据模型部分;View是界面展示部分;而ViewModel比较特殊,可以将它理解成一个连接数据模型和界面展示的桥梁,从而实现让业务逻辑和界面展示分离的程序结构设计。 - 这里是列表文本当然,一个优秀的项目架构除了会包含以上3部分内容之外,还应该包含仓库、数据源等,这里我画了一幅非常简单易懂的MVVM项目架构示意图, MVVM项目架构示意图![输入图片说明](https://res.weread.qq.com/wrepub/epub_37683759_402 "在这里输入图片标题") - MVVM项目架构示意图可以看到,我们通过这张架构示意图将程序分为了若干层。其中,UI控制层包含了我们平时写的Activity、Fragment、布局文件等与界面相关的东西。ViewModel层用于持有和UI元素相关的数据,以保证这些数据在屏幕旋转时不会丢失,并且还要提供接口给UI控制层调用以及和仓库层进行通信。仓库层要做的主要工作是判断调用方请求的数据应该是从本地数据源中获取还是从网络数据源中获取,并将获取到的数据返回给调用方。本地数据源可以使用数据库、SharedPreferences等持久化技术来实现,而网络数据源则通常使用Retrofit访问服务器提供的Webservice接口来实现。 - 另外,对于这张架构示意图,我还有必要再解释一下。图中所有的箭头都是单向的,比方说UI控制层指向了ViewModel层,表示UI控制层会持有ViewModel层的引用,但是反过来ViewModel层却不能持有UI控制层的引用,其他几层也是一样的道理。除此之外,引用也不能跨层持有,比如UI控制层不能持有仓库层的引用,谨记每一层的组件都只能与它相邻层的组件进行交互。 - 那么接下来,我们会严格按照刚才的架构示意图对SunnyWeather这个项目进行实现。为了让项目能够有更好的结构,这里需要在com.sunnyweather.android包下再新建几个包,如图所示。![输入图片说明](https://res.weread.qq.com/wrepub/epub_37683759_403 "在这里输入图片标题") - 项目的新结构很明显,logic包用于存放业务逻辑相关的代码,ui包用于存放界面展示相关的代码。其中,logic包中又包含了dao、model、network这3个子包,分别用于存放数据访问对象、对象模型以及网络相关的代码。而ui包中又包含了place和weather这两个子包,分别对应SunnyWeather中的两个主要界面。 - 另外,在整个项目的开发过程中,我们还会用到许多依赖库,为了方便后面的代码编写,这里就提前把所有会用到的依赖库都声明一下吧。编辑app/build.gradle文件,在dependencies闭包中添加如下内容: - ` dependencies { implementation 'androidx.recyclerview:recyclerview:1.0.0' implementation "androidx.lifecycle:lifecycle-extensions:2.2.0" implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.2.0" implementation 'com.google.android.material:material:1.1.0' implementation?"androidx.swiperefreshlayout:swiperefreshlayout:1.0.0" implementation 'com.squareup.retrofit2:retrofit:2.6.1' implementation 'com.squareup.retrofit2:converter-gson:2.6.1' implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.0" implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.1.1" } ` - 这几个库全部都是我们在前面的章节中使用过的,相信对你来说应该不难理解。由于我们引入了Material库,所以一定要记得将AppTheme的parent主题改成MaterialComponents模式,也就是将原来的AppCompat部分改成MaterialComponents即可。 #### 安装教程 1. xxxx 2. xxxx 3. xxxx #### 使用说明 1. GookieBar 使用 `` top: CookieBar.builder(getActivity()) .setTitle(R.string.title_password) .setMessage(R.string.tip_password_error) .show(); bottom: CookieBar.builder(getActivity()) .setTitle(R.string.title_password) .setIcon(R.mipmap.ic_launcher) .setMessage(R.string.tip_password_error) .setLayoutGravity(Gravity.BOTTOM) .setAction(R.string.cookie_action, view13 -> XToastUtils.toast("点击消失!")) .show(); top_with_icon: CookieBar.builder(getActivity()) .setMessage(R.string.tip_password_error) .setDuration(-1) .setActionWithIcon(R.drawable.ic_action_close, view12 -> XToastUtils.toast("点击消失!")) .show(); custom: CookieBar.builder(getActivity()) .setTitle(R.string.title_password) .setMessage(R.string.tip_password_error) .setDuration(3000) .setBackgroundColor(R.color.colorPrimary) .setActionColor(android.R.color.white) .setTitleColor(android.R.color.white) .setAction(R.string.cookie_action, view1 -> XToastUtils.toast("点击消失!")) .show(); `` 2. XuiToast 使用 `` XToast.Config.get() //位置设置为居中 .setGravity(Gravity.CENTER) XToastUtils.error(R.string.error_message); XToastUtils.success(R.string.success_message); XToastUtils.info(R.string.info_message); XToastUtils.warning(R.string.warning_message); XToastUtils.toast(R.string.normal_message_without_icon); `` 3. loading 使用 **带图标的loading** #定义 ``private lateinit var mLoadingDialog:LoadingDialog mLoadingDialog = WidgetUtils.getLoadingDialog(MyApplication.context) .setIconScale(0.4f) .setLoadingSpeed(8) `` #使用 ``mLoadingDialog.show() `` #关闭 ``mLoadingDialog.dismiss() `` #资源释放 fragment 中 ``override fun onDestroyView() { mLoadingDialog.recycle() super.onDestroyView() } `` #资源释放 activity中 ``override fun onDestroy() { mLoadingDialog.recycle() super.onDestroy() } `` **xml中使用loading** #引入 ` ` #调用 `` val loadingViewLayout = findViewById(R.id.loading_view_layout) as LoadingViewLayout loadingViewLayout.show() `` #关闭 ``loadingViewLayout.dismiss() `` #销毁 `` loadingViewLayout.recycle()`` **普通loading** #定义 `` private lateinit var mMiniLoadingDialog:mMiniLoadingDialog mMiniLoadingDialog = WidgetUtils.getMiniLoadingDialog(requireContext(),"努力加载中"); `` #调用 ``mMiniLoadingDialog.show()`` #关闭 ``mMiniLoadingDialog.dismiss()`` #销毁 ``mMiniLoadingDialog.recycle()`` ### ViewModel 共享 https://developer.android.com/codelabs/basic-android-kotlin-training-shared-viewmodel?hl=zh-cn&continue=https%3A%2F%2Fdeveloper.android.com%2Fcourses%2Fpathways%2Fandroid-basics-kotlin-unit-3-pathway-4%3Fhl%3Dzh-cn%23codelab-https%3A%2F%2Fdeveloper.android.com%2Fcodelabs%2Fbasic-android-kotlin-training-shared-viewmodel#4 #### 感谢贡献 1. https://github.com/gyf-dev/ImmersionBar #### 特技 1. 如何使用XUI [https://gitee.com/xuexiangjys/XUI#%E7%89%B9%E5%BE%81](https://gitee.com/xuexiangjys/XUI#%E7%89%B9%E5%BE%81) ### 热修复使用 # 注意事项 1、确保没有新增四大组件,没有修改AndroidManifest.xml和入口Application中的代码。 2、如果使用了混淆,确保打包使用的新旧包的混淆保持已经确保一致,如新包apply了旧包的mapping文件。 3、如果使用了加固,确保打包使用的新旧包都是加固前的正常包。 4、如果有资源修复,确保没有修改通知栏图标、启动图标资源以及RemoteViews等系统负责展示的资源。 5、如果有SO库的修复,确保所需要修复的SO都是以System.loadLibrary的方式,而不是以具体路径的方式进行加载。 # 制作基线包 1.确保build。gradle 中的版本、SophixStubApplication 中的appVersion、 config.appVersion 、阿里云后台的版本后一致,否则会找不到patch包 2.打开混淆文件中的-printmapping mapping.txt 注释掉-applymapping mapping.txt 3.gradle打包 4.安装 #制作修复包 1.不要改版本号,并且看注意事项 2.打开混淆文件中的-applymapping mapping.txt 注释掉-printmapping mapping.txt 3.gradle打包 4.SophixPatchTool制作差异包补丁,旧包选基线包,新包选修复包,然后go! 5.上传到阿里云EMAS 热修复控制台版本注意要与基线包制作中的版本一样 6.发布之后app启动后稍作等待 待补丁下载,加载,生效完成(一般几秒钟内就可以)