博客已迁移旧博客的所有内容已迁移至本站,原站点将不再更新,后续所有东西我会慢慢搬过来。
为什么迁移因为之前的 GitHub 号被封了影响到了托管的站点,在我有一天心血来潮想传点东西的时候发现的……也不必去考古,~~ 因为其实我也就传了一篇帖子在网上,其他基本在本地 ~~ 虽然后面与伟大且高效的 GitHub 官方进行了一番交谈解除了限制(原因竟是有个仓库名写了 f**k ???),但事已至此,新号也创建了,网站也备案了……就让他成为过去吧。ಥ_ಥ
迁移说明
文章:会慢慢上传的,也许吧,因为我个人喜欢把东西存本地。
评论区:本站暂不开启评论功能。
主题: 主题从 Butterfly 换成了 Anzhiyu,但我感觉花里胡哨的,自由度也不是很大,后面看情况再考虑换不换吧。此外我不建议你打开白天模式,因为会出现一些 UI 配色问题。
感谢你一直以来的关注
绪论APP 开发者往往着眼于 UI 界面的搭建与功能实现,这很正常。毕竟一个 APP 的亮点与特色是什么,吸引用户与否,实用创新的功能和简洁美观的 UI 往往占大头。但近几年来,AI 正在把“搭建”这件事变得越来越廉价。去年这时我还在 CSDN 里搜索某功能逻辑怎么写;而现在写好提示词后,丢给 AI,几分钟便能生成一套像模像样的页面,连对应功能的实现也一并给了。
但在性能优化方面,很遗憾,我没打算昧着良心安慰你说 AI 做不到。目前,Agent 能跑构建、查日志、扒源码,只要你给的权限足够,让它在模拟器上跑一遍关键用户路径生成 .prof 文件,或是在真机上连续冷启动测平均启动时长等,这些只要写好提示词,或配好 Skill,都能实现。
当然,这一切都建立在你得知道有这些东西的前提上,AI 默认你没问,就不会为你主动考虑得面面俱到。而在短期主义的驱使下,绝大多数人也确实不会问,毕竟代码能跑就行,需求没提关我啥事。AI 时代下,知识面的宽度很大程度上影响产出质量的下限(深度也很重要),在你什么都不了解的情况下,就很容易变成 AI 给什么就验收什么。而模型输出靠的是统计学上最常见的写法,并不 ...
积善之家,必有余庆。
前言《余庆集》原名本非如此,在这里我也没打算分享它的真名,至于为什么现在叫这个名字,因为余庆只是我的笔名罢了。
关于《余庆集》由来的记忆我早已模糊,也不必深究,依稀记得是在我初中时期就已经存在了。时至今日,20 岁的我再次点开它时,竟有一种莫名的割裂感,几年前的我是我吗?
《余庆集》主要分为长生、虚无、风骚、破陈(尘)、余庆。
这里主要陈列余庆篇里的内容,有些部分因为某些原因选择糜烂在心里或做删改。
余庆篇
我讽喻过,我豪放过,我抒情过,我悼亡过,我怀古过,我山水过,我婉约过,我闺怨过,我羁旅过,我朦胧过… 过去的一切已逝去,将来又虚无缥缈……
因为我对平仄与韵律研究的不深,这些姑且算古体诗吧。
晚山行嶙峋乱石三六壁,晚山幽径寒草迷。
古道悲魂凄凉诉,绕树残鸦不肯栖。
我近十八不得意,清贫身披飞鹑衣。
神憎鬼厌无人济,惟有孤影不相离。
西风萧兮枝摇曳,星汉淡兮月渐移。
忽逢远处有人家,烟袅烛明门半掩。
主人怜我囊如洗,邀我共饮流水边。
狗睡池鱼寂无声,梦中故园何时还?
精怪鸠聚仙雀喧,妖言魅泣自难眠。
长夜众咻何由彻?鸡啼晓破万邪湮。
无 ...
计算机
未读声学与数字信号处理将声音由模拟信号转化成数字信号需要采样、量化、编码。
PCM 脉冲编码调制,就是这三个步骤的统称。转化后的数据就是没有压缩过的原始音频数据。经由此过程产生的、没有任何处理的二进制数字序列也可以称作 PCM 或 PCM音频数据流。
那模拟声音信号是怎么来的呢?答案是麦克风设备采集。我们说话时声波在空气中传播,麦克风内部的振膜被声波推动产生振动,进而转换成连续变化的微弱电压信号。
PCM 过程是在 ADC(模数转换器)上执行的。ADC 是声卡内部的一个核心元件。
采样 简单来说,就是把连续变化的模拟信号每隔一定时间取个值,也就是进行离散化的切割,并获取采样点的模拟值。可想而知,点越多越密集,越能近似表示原来的波形,声音保真度越高,质量越好;但记录数据越多,存储容量越高。
每秒采样声音的次数称作采样频率,单位是 Hz 。
量化 将采样点的值分级量化,变换到最接近的数字,也就是用有限个数近似表示原来连续变化的值。分级越多,采样点取值更精确,声音质量越好;但同理二进制的位数更多,存储容量越大。
量化值的二进制位数称作量化位数,也叫位深
编码 将这些整数转换成二进制码。
...
对的,就是 TTS,文字朗读
安卓平台提供 TTS 相关功能的 API,对于基本的文字转语音需求还是足够的,当然朗读的音色似乎很人机,要实现更丰富的语音还是调用云端 TTS 相关 API 吧。
初始化 TextToSpeech初始化 TextToSpeech ,因为初始化过程是异步的,需要在回调中检查初始化状态是否成功,等引擎加载成功后再进一步配置、播报。
123456tts = TextToSpeech(context.applicationContext) { status -> if (status == TextToSpeech.SUCCESS) { configure(tts)// 配置 startSpeaking(messageId, content)// 朗读 }}
配置配置的话,可以进行一系列配置,太晚了先睡觉吧。
在 Android 项目开发中,统一管理插件版本和第三方库依赖十分重要,Gradle 提供的 Version Catalog (TOML) 方便我们通过libs.versions.toml文件集中管理所有依赖和插件的版本。
TOML 文件在项目根目录的 gradle/libs.versions.toml 里,如果文件视图中选择 Android 的话也很容易在 Gradle Scripts 里找到。
古老硬编码写法喂,这样明明很方便的好吧
在早期的 Gradle 配置中,我们通常在 build.gradle.kts 文件中直接声明插件和依赖库。不过现在新版的 Android Studio 刚创建项目后应该也看不见它的身影了。在一些教程里为了方便,依赖引用声明常常直接导入。
——历史的博物馆——
根项目的 build.gradle.kts
1234plugins { id("com.android.application") version "9.2.1" apply false id("org.jetbrain ...
Android
未读SharedPreferences 想必都知道吧,是所有安卓人学数据持久化的入门必修课,它可以通过简单的键值对 (Key-Value) 方式来轻松存储和获取各种基本数据类型,在开发中常用于存储简单的应用配置、登录状态和用户偏好等等。
但它也有许多令人诟病的,比如无论 edit 还是 commit 都有可能引发 ANR ,容易阻塞线程,类型不安全,数据一致性难保等等。
反正我目前是还没遇到过
所以都 2026 了还有人在用 SP 吗?
官方:Welcome Jetpack DataStore, now in alpha - a new and improved data storage solution aimed at replacing SharedPreferences.
??????
介绍DataStore 是个什么❓
依旧美美照搬
Jetpack DataStore 是一种数据存储解决方案,让您可以使用协议缓冲区存储键值对或类型化对象。DataStore 使用 Kotlin 协程和 Flow 以异步、一致的事务方式存储数据。
DataStore 的分类DataStore ...
ArkTS 入门ArkTS 简介ArkTS 是 HarmonyOS APP 应用开发的默认开发语言,在 TypeScript 生态基础上做了进一步扩展和规范定义,强化了开发期的静态检查和分析,提升了程序执行的稳定性和性能。ArkTS 同时也支持与 TS/JS 高效互操作。
它与 TS 的区别主要有:
类型更加严格,强制静态类型,禁用了 any 类型,而且强制显式标注
通过 ArkCompiler(方舟编译器)AOT 编译为方舟字节码或机器码,在方舟运行时中执行。
删减了部分动态特性,如 with 语句、运行时类型反射等。
扩展了并发模型,除了 Promise 外,特有 TaskPool与 Worker。
在网上很容易看到类似这种图来表示 JS , TS , Arkts 关系的,但由于 ArtTS 的限制和拓展,严格来说 ArkTS 并非 TS 的超集,因为它并非像 TS 之于 JS 那样基本上是只增加不减少,而是在 TS 语法之上做了减法(如上面所说的砍掉动态特性),在平台能力上进行拓展(增加了鸿蒙专用 的API)。
下次更新将在后文追加……
Android
未读在 APP 开发中很多效果往往都需要动画的配合来实现。 Android 提供了多种动画类型,如属性动画和视图动画,其中视图动画又包括帧动画和补间动画。
属性动画说实话没什么高大上的,它的原理也很简单粗暴,无非就是通过不断调用 setXxx 方法修改对象的 属性值(比如 translationX 、alpha 等等),并配合重绘,以达到动画的效果。
ViewPropertyAnimator想让一个 View 动起来,可以用 ViewPropertyAnimator 简单实现。通过 View.animate() 可以返回一个 ViewPropertyAnimator 对象,拿到它之后就可以 为所欲为 操作 View 了 。
1234public ViewPropertyAnimator animate() { throw new RuntimeException("Stub!"); }view.animate().translationX(500);//让 view 水平移动500
基本用法因为属性动画是通过不断操作 View 的属性来 ...



