- 博客(104)
- 收藏
- 关注
原创 String、StringBuilder、StringBuffer的由来与作用
在大多数现代应用中,单线程场景更为常见,因此StringBuilder的使用频率通常高于StringBuffer。
2025-07-29 18:35:39
142
原创 Kotlin Flow 在 Jetpack Compose 中的正确打开方式:SharedFlow vs StateFlow 与 LaunchedEffect
本文深入探讨了Jetpack Compose中Kotlin Flow的使用,重点对比了SharedFlow和StateFlow的特性与适用场景。SharedFlow适合处理一次性事件(如Toast、导航),需配合LaunchedEffect使用;StateFlow则用于持久状态管理(如加载状态),推荐使用collectAsState自动更新UI。文章还解答了常见问题,并提供了清晰的选择指南:事件用SharedFlow+LaunchedEffect,状态用StateFlow+collectAsState,手动
2025-07-26 14:30:31
904
1
原创 Kotlin Flow 实战:StateFlow 和 SharedFlow 的默认值陷阱
摘要:本文对比了Kotlin中StateFlow和SharedFlow的核心差异,通过文件路径选择案例揭示了StateFlow初始值触发的常见问题。StateFlow适合UI状态管理(需初始值),而SharedFlow更适合事件流(无初始值)。文章提供了两种解决方案(改用SharedFlow或过滤初始值),并给出Jetpack Compose中的使用示例。开发者应根据场景选择:UI状态用StateFlow,事件流用SharedFlow,需要跳过初始值时配合filter/drop操作符。
2025-07-23 02:20:51
450
原创 解决jetbrains快速构建的KMP项目运行Desktop提示错误: 找不到或无法加载主类 原因: java.lang.ClassNotFoundException
3、运行成功,将这个命令指令保存配置,以后就可以直接点击三角形运行。2、点击第二个图标 Execute Gradle Task,输入。1、点击Gradle图标。
2025-07-21 19:02:26
192
原创 你以为有引用就不会被GC?详解Java四种引用类型的回收策略
文章摘要:Java中的引用类型分为强引用、软引用、弱引用和虚引用四种。强引用对象不会被GC回收;软引用在内存不足时回收;弱引用每次GC都会被回收;虚引用仅用于跟踪对象回收状态。不同引用类型适用于不同场景,如强引用用于普通对象,软引用适合缓存,弱引用可避免内存泄漏,虚引用用于资源清理跟踪。合理选择引用类型可以优化内存管理,避免内存泄漏。
2025-07-20 18:19:35
880
原创 Android 主线程入口:ActivityThread 是所有组件的必经之路吗?
本文深入解析Android主线程的启动机制,指出ActivityThread.main()是所有组件生命周期的必经之路。它初始化了主线程的Looper、Handler和MessageQueue三大核心组件,构成了消息循环机制。虽然Activity、Service、Broadcast等组件有各自的业务入口方法,但最终都依赖主线程的Handler进行调度。文章通过代码分析和流程图说明,即使应用仅通过Service或广播启动,ActivityThread.main()仍会执行以确保主线程正常运行。最后用火车站类比
2025-07-20 11:45:06
1094
原创 为什么说Activity就是一个Context?一文读懂Android上下文设计精髓
角色生活场景Android组件Context能力服务员前台接待顾客Activity有UI权限,能启动其他页面厨师后台做菜Service无UI,但能长期运行餐厅老板掌握全局资源生命周期最长,全局信息餐厅本身提供水电、仓库Context基础支持(资源、系统服务访问)核心思想:Context是Android组件的“生存环境”,而Activity、Service等是不同职责的“员工”,他们能用的权限不同,但都依赖Context提供的基础支持。
2025-07-20 03:32:46
771
原创 为什么下载的人越多越快?深入解析P2P技术的魔力
比如用BitTorrent下载时,我的客户端会同时连接几十个Peer,每个Peer提供不同的块,即使最后一块也可能从某个Peer快速获取——这完全符合点对点定义,因为每个连接都是独立的P2P通道。这听起来有点反直觉——通常我们觉得用的人越多,网络应该越拥堵才对,为什么P2P(Peer-to-Peer,点对点)下载反而会加速呢?今天,我们就来深入探讨P2P技术的核心原理,看看它是如何实现“人越多越快”的,以及它在现代互联网中的应用。,你的下载速度不再受限于单一服务器,而是所有Peer的上传带宽之和!
2025-07-19 14:53:09
693
原创 跑步机上的Android Handler:用生活场景秒懂消息机制
Handler机制核心流程解析 消息管理 Handler通过sendMessage()/post()将任务封装为Message,按执行时间排序插入单向链表的MessageQueue(优先级队列)。 立即执行的消息(when=0)置于队首,延迟消息通过SystemClock.uptimeMillis()保证时序。 消息循环 Looper.loop()死循环调用queue.next(): 取出队首消息(时间最近的任务) 队列空时,nativePollOnce()使线程阻塞 通过msg.target.dispat
2025-07-18 15:45:23
542
原创 音视频同步技术初剖析:原理、实现与FFmpeg分析
音视频同步主要依靠以下几个关键点:时间戳机制:同步策略:实现方式:在Android开发中,通常通过以下方式实现:MediaSync类:自定义同步:以下是伪代码示例,展示如何用音频PTS同步视频:关键参数::同步阈值(通常设10-40ms),超出阈值才触发调整。动态策略:根据设备性能调整阈值(性能差时增大阈值,减少频繁丢帧)。SurfaceView/TextureView:结合上述同步逻辑,在正确的时间点将视频帧渲染到Surface上可能遇到的问题及解决方案时钟漂移:帧率不匹配
2025-07-17 15:37:39
552
原创 数字音视频存储揭秘:如何计算PCM音频与YUV/RGB视频的原始文件大小
让我们先来计算一下PCM(脉冲编码调制)音频文件的大小。所以,1分钟的44.1kHz、16bit、立体声PCM音频大约为10.09MB。
2025-07-17 03:39:51
711
2
原创 【学习笔记】ARouter路由模块的设计思想与源码实现
组件化路由方案设计 本文探讨了Android组件化开发中的路由系统实现方案。初始版本采用Map存储路由关系,存在注册代码冗余问题。改进方案引入IRouterLoad接口,让各组件自行注册路由。核心难点在于如何动态发现所有实现该接口的类,通过分析DexFile加载机制,提出利用PackageManager获取APK路径,再通过反射扫描指定包名下所有类,筛选出路由实现类进行自动注册。该方案实现了组件间的解耦,避免了手动注册的繁琐,为组件化开发提供了高效的路由解决方案。
2025-07-16 01:36:05
861
原创 Kotlin协程中的Job与SupervisorJob:理解它们的区别
特性Job异常传播向上传播,取消所有子协程不传播,仅取消失败协程使用场景需要原子性操作需要独立运行的子任务子协程独立性低高异常处理方式集中处理分散处理:确实使用了:同样使用了设计意图:这种设计使Android的协程Scope更适合UI开发场景,提供了更合理的默认行为。
2025-07-15 16:10:51
685
原创 在NDK开发中如何正确创建JNI方法
在Android NDK开发中,Java Native Interface (JNI) 允许Java代码与C/C++代码交互。正确创建JNI方法对于确保Java能够正确调用本地代码至关重要。本文将详细介绍如何在C++文件中创建JNI方法。
2025-07-13 16:59:44
954
原创 从 OpenCore 到 MediaCodec:Android 多媒体引擎演进史
在 Android 多媒体框架中,和是历史上先后出现的两个核心多媒体引擎,它们负责音视频的编解码、播放、录制等关键功能。随着 Android 版本的迭代,它们的角色逐渐演变,最终被更现代的架构(如)取代。
2025-07-10 01:54:13
653
原创 【学习笔记】OkHttp源码架构解析:从设计模式到核心实现
我们都知道:call带着request前往分发器dispatcher,分发器需要看情况这个请求要到哪个队列,比如当正在请求的队列满了就需要去等待队列,不难得出我们需要写出一个Dispatcher,并且至少维护着两个队列,且这两个队列是非阻塞队列;然而现在我们知道队列里放的是请求,但能不能直接放request进去呢?关于责任链这里,我们都知道okhttp设计各种拦截器的主要原因,一个是为了把重试、请求头、获取长链接以及真正请求的逻辑去做一个解耦,另一个原因也是为了让开发者可以自定义增加或者删除拦截器。
2025-07-09 16:37:23
604
原创 Windows平台下Android Studio搭建Flutter开发环境的正确姿势(202506)
通过以上步骤,你应该已经成功搭建了Flutter开发环境。Flutter的热重载功能可以让你快速看到代码更改的效果,极大地提高了开发效率。现在,你可以开始探索Flutter丰富的组件库和强大的跨平台能力,构建出色的移动应用了!如果你在安装过程中遇到任何问题,欢迎在评论区留言,我会尽力解答。
2025-06-27 17:23:19
666
原创 深入解析Activity的视图层级:从Activity到ContentView的完整链路
Activity作为入口持有创建并管理DecorViewDecorView包含默认的垂直LinearLayout这个LinearLayout中包含标题栏和内容容器(FrameLayout)我们通过设置的布局最终被添加到内容容器中理解这个完整的视图层级关系,能够帮助开发者更好地控制应用界面,进行更高效的性能优化,以及解决复杂的UI问题。
2025-06-24 15:12:06
597
原创 注解处理器 vs 反射:一个简单示例的深度对比
Target(ElementType . TYPE) // 只能用在类上 @Retention(RetentionPolicy . RUNTIME) // 运行时保留 public @interface Hello {@Target(ElementType . TYPE) // 只能用在类上 @Retention(RetentionPolicy . RUNTIME) // 运行时保留 public @interface Hello {
2025-06-19 01:28:33
230
原创 Android App启动流程深度解析(一):从Activity.startActivity开始
在Android应用开发中,启动流程是最基础也是最重要的机制之一。作为一名Android开发者,理解应用启动的完整流程对于性能优化、问题排查和架构设计都至关重要。本系列文章将从最上层的方法开始,自上而下深入分析Android应用启动的完整流程。
2025-06-17 00:04:09
860
原创 解决Windows 11 24H2运行VMware提示“此平台不支持虚拟化的 amd-v/rvi”的问题
问题描述升级Windows 11 24H2后,VMware Workstation突然报错:“此平台不支持虚拟化的amd-v/rvi”。经查证,这是微软在24H2版本中强制启用了基于虚拟化的安全功能(VBS),与第三方虚拟化软件产生冲突。以下是本人通过实践验证的7种解决方案。在尝试任何修改前,请先确认当前状态:效果:对24H2版本通常无效,但建议首先尝试修改或新建DWORD值:方案3:关闭内存完整性(GUI操作)打开 Windows 安全中心 → 设备安全性进入"内核隔离" → 关闭"
2025-06-16 15:52:49
1502
原创 深入理解数字音频:采样率、位深与量化
数字音频是将连续的模拟声音信号转换为离散的数字表示的过程。与传统的模拟录音(如黑胶唱片或磁带)不同,数字音频以二进制数据的形式存储声音信息,这使得音频可以被精确复制、编辑和处理而不会损失质量。理解采样率、位深、香农定理和量化等概念不仅对音频工程师至关重要,对于任何希望在数字时代更好地欣赏和利用声音的人来说都极具价值。无论你是音乐爱好者、播客创作者还是视频制作人,掌握这些基础知识将帮助你做出更明智的技术选择,从而获得最佳的音频体验。
2025-06-06 17:33:50
1116
原创 从餐厅点餐到安卓相机:揭秘Binder跨进程通信机制
在安卓系统中,Binder机制扮演着关键角色,类似于餐厅中的服务员,协调APP(顾客)与系统服务(厨房)之间的交互。Binder的核心功能包括跨进程通信、权限管控和高效数据传输。通过Binder,APP可以请求系统服务,如摄像头访问,而系统服务则通过Binder验证权限并处理请求。即使是系统自带的相机APP也需要通过Binder进行通信,确保数据隔离和安全性。Camera2相较于Camera1,通过引入共享内存(ashmem)优化了数据传输效率,减少了内存拷贝的开销,提升了性能。Binder与ashmem的
2025-05-19 16:50:41
988
原创 深入浅出:CPU寻址方式完全指南(从理论到实践)
寻址方式是CPU定位操作数的策略,决定了指令如何访问数据,影响程序的效率、灵活性和硬件设计。CPU执行指令时,操作数可能存放在指令自身、寄存器或内存中。为了高效访问数据,诞生了多种寻址方式,每种方式在速度、灵活性和指令长度之间权衡。常见的寻址方式包括立即寻址、寄存器直接寻址、直接寻址、寄存器间接寻址、基址寻址、变址寻址和堆栈寻址。通过理解这些寻址方式,可以更好地理解汇编代码,并写出更高效的高级语言代码。学习寻址方式时,应理解其本质,画图辅助,对照实践,并关联高级语言。
2025-05-18 18:14:42
606
原创 Android核心系统服务:AMS、WMS、PMS 与 system_server 进程解析
本文深入探讨了Android系统中三个核心服务——ActivityManagerService (AMS)、WindowManagerService (WMS)和PackageManagerService (PMS)的作用及其在system_server进程中的运行机制。AMS负责应用生命周期管理,WMS处理窗口显示与交互,PMS管理应用包的安装与权限。这些服务并非独立进程,而是运行在system_server进程的不同线程中,以减少进程间通信的开销并提高系统性能。system_server是一个多线程进程
2025-05-17 19:12:17
1706
原创 计算机组成原理 vs. 现实硬件:你的电脑里到底藏着什么?
当你组装电脑时,看到的只是 **主板、CPU、内存条、硬盘、显卡** 这些大块头的硬件。但《计算机组成原理》里讲的却是 **运算器、控制器、寄存器、总线、Cache、ROM** 这些抽象概念。它们之间到底怎么对应?为什么装机时看不到这些“神秘组件”?这篇博客带你揭开计算机硬件的“微观世界”
2025-05-14 18:34:45
969
原创 Android NDK开发入门:理解JNI的本质与数据类型处理
本文深入探讨了Android NDK开发的核心机制,重点分析了JNI中基本类型与对象类型的处理差异,并提供了调用第三方C库的完整流程。NDK通过编译C/C++代码和提供JNI桥梁,实现了Java/Kotlin与原生代码的交互,适用于性能优化、复用现有库和底层操作等场景。在JNI中,基本数据类型可以直接返回,而对象类型(如String)必须通过JNIEnv创建。文章还详细解释了Kotlin基本类型在JNI中的处理方式,并提供了调用第三方C库的步骤,包括集成C库和编写JNI包装函数。通过实际代码示例,帮助开发者
2025-05-12 10:50:36
765
原创 Android Canvas API 详细说明与示例
本文介绍了Android中Canvas绘制的基本图形、路径、文字、位图以及变换和图层操作的方法。通过示例代码详细展示了如何绘制直线、矩形、圆角矩形、圆形、三角形等基本图形,以及如何使用Path类绘制贝塞尔曲线。此外,还介绍了文字绘制、位图绘制以及平移、旋转、缩放等变换操作。最后,讲解了如何创建和操作图层。掌握这些API的使用方法和参数含义,可以帮助开发者在自定义View时实现复杂的绘制效果。
2025-05-11 16:37:11
621
原创 C语言的中断 vs Java/Kotlin的异常:底层机制与高级抽象的对比
在编程世界中,"中断"和"异常"都是程序执行流程被意外打断的情况,但它们的实现机制和适用场景截然不同
2025-05-10 13:04:18
769
原创 深入理解Android自定义View:onMeasure、onLayout与onDraw详解
系统提供的标准View无法满足需求需要高度定制化的UI组件创建可重用的特殊UI组件实现特殊的动画或交互效果Android提供了完善的View系统,让我们可以通过继承View或现有View类来实现自定义功能。是自定义View中最常用的方法,负责绘制View的视觉内容。使用Canvas对象进行绘制操作使用Paint对象定义绘制样式避免在onDraw中创建新对象(防止内存抖动)需要重绘时调用invalidate()或postInvalidate()@Override。
2025-05-08 13:02:06
915
原创 Android 从模板代码到通用工具:ViewBinding的演进之路
DRY原则的价值:不要重复你自己语言特性(反射/reified)的巧妙运用工程中在性能与开发效率间的合理权衡这种演进不是过度设计,而是随着项目复杂度提升的自然选择。理解背后的技术决策过程,比单纯记忆实现方式更有价值。
2025-05-07 11:36:08
543
原创 Android SDK 开发中的 AAR 与 JAR 区别详解
在 Android SDK 开发中,构建项目时我们常常会看到生成两个不同的文件:一个是 `build/outputs/aar/*.aar`,另一个是 `build/intermediates/aar_main_jar/debug/syncDebugLibJars/classes.jar`。很多初学者会疑惑:它们之间有什么区别?为什么构建会生成两个包?本篇博客将从生成路径、结构内容和使用场景三个角度,系统解释 AAR 和 JAR 的差异
2025-05-06 16:57:01
739
原创 Kotlin DSL 深度解析:从 Groovy 迁移的困惑与突破
Gradle 作为现代构建工具,支持 **Groovy** 和 **Kotlin** 两种 DSL(领域特定语言)。Kotlin DSL 因其**类型安全**和**更好的 IDE 支持**逐渐流行,但它的语法设计却让许多开发者感到困惑,尤其是从 Groovy 迁移时。 本文将从 **Kotlin DSL 的基本概念** 出发,通过 `build.gradle` 示例对比 Groovy 和 Kotlin 的差异,并深入探讨那些**晦涩难懂的语法**,最后解析 `tasks.register<Copy>(
2025-04-28 09:40:45
1167
原创 Android 理清 Gradle、AGP、Groovy 和构建文件之间的关系
在 Android 开发中,我们常常会接触到一系列看似相近却各有分工的名词,比如:**Gradle**、**Groovy**、**AGP**、**gradle-wrapper.properties**、**build.gradle**、**settings.gradle** 等等。 它们彼此之间到底是什么关系?各自又承担了什么角色?本文将用清晰的结构,一次性帮你理清!
2025-04-27 13:16:36
1387
原创 Kotlin高阶函数 vs Lambda表达式:关键区别与协作关系
在 Kotlin 中,高阶函数(Higher-Order Function)和 Lambda 表达式密切相关,但它们是两个不同的概念
2025-04-23 14:48:04
718
原创 Kotlin 协程在 LiveData 中的完美封装:CoroutineLiveData 全解
`CoroutineLiveData` 是 `liveData` 构造器创建出来的 `LiveData` 对象,它是 Jetpack 中为协程量身打造的 `LiveData` 版本,主要用来让我们在 `LiveData` 的作用域内,安全、方便地使用协程
2025-04-23 11:09:38
899
原创 迁移到 Android Jetpack Compose 的第一个理由:告别 RecyclerView 的复杂形式
在传统 Android UI 开发中,RecyclerView 是构建列表 UI 的标配组件,但是当需要处理多种不同类型的 item 时,它的编写成本和维护成本会突然上升。这不仅是编码的煮烤,还有一堆策略不符 SRP、OCP 等设计原则的问题。而 Jetpack Compose 的出现,则从根本上解决了这一系列问题,并提供了更现代、声明式、易维护的规划方式
2025-04-22 16:05:25
560
原创 Android RecyclerView 多布局场景下的设计思考:SRP 与 OCP 的权衡与优化
在日常 Android 开发中,RecyclerView 是我们用得非常频繁的一个组件,而与之搭配使用的 Adapter 则承担着数据与视图之间的桥梁作用。本文将围绕 Adapter 的本质角色、多布局场景下是否违反面向对象的设计原则(单一职责原则 SRP 与 开闭原则 OCP),以及如何更优雅地应对复杂场景进行系统性梳理
2025-04-22 09:34:47
914
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人