自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(103)
  • 收藏
  • 关注

原创 在compose页面中显示JAVA自定义控件

Compose 中嵌入 Java 自定义控件的核心是组件,它实现了 Compose 与原生View的桥接。无状态交互直接通过factory创建并初始化控件,有状态交互通过结合update实现双向同步。关键是遵循 “factory创建一次,update按需刷新” 的原则,兼顾功能完整性和性能。

2026-01-10 23:59:21 917

原创 如何处理Java自定义控件与Compose状态的联动?

适用场景:Compose 状态变更(如其他 Compose 组件触发),需要同步刷新 Java 自定义控件的 UI(如文本、颜色、进度等)。适用场景:Java 控件的用户交互事件(如点击、滑动、输入),需要同步更新 Compose 状态,供其他 Compose 组件使用。双向联动是上述两种单向联动的结合,实现 “Compose 状态变更同步到 Java 控件,Java 控件事件也同步到 Compose 状态”,是最常用的场景(如输入框、开关控件等)。Compose 可观察状态Java 控件公开方法/监听器。

2026-01-10 23:34:45 902

原创 Android中四大组件之一的Activity的启动模式

standard:默认模式,每次新建实例,适合普通页面;singleTop:栈顶复用,避免栈顶重复创建,适合通知 / 搜索页面;singleTask:栈内单例,清理上方页面,适合应用核心页面(如首页);:全局单例 + 独立栈,仅用于系统级 / 强隔离页面,极少使用。核心原则:根据页面的 “复用需求” 和 “任务栈隔离需求” 选择启动模式,优先使用 standard/singleTop/singleTask,避免滥用 singleInstance。

2026-01-08 18:59:59 1134

原创 HTTP/1.1 + HTTP/2 + HTTP/3 之间的区别

HTTP/1.1:解决了 “短连接频繁握手” 的问题(长连接),但并发能力差,是互联网早期的基础协议;HTTP/2:解决了 “HTTP 层队头阻塞”(多路复用),优化了头冗余(HPACK),但未解决 TCP 层的根本问题;HTTP/3:解决了 “TCP 层队头阻塞”(基于 UDP),优化了连接稳定性(QUIC 连接 ID)和握手速度(0-RTT),是为移动 / 弱网环境设计的下一代协议。首次连接留存加密的会话凭证,后续连接直接用凭证加密业务数据并发送,无需等待服务器握手响应;

2025-12-17 19:08:22 945

原创 OKHttp 核心原理

用户可通过添加,仅在「走网络的请求」中执行(缓存命中时不执行),常用于监控网络请求、修改请求 / 响应(如抓包、埋点)。应用层配置 → 拦截器链(重试/缓存/连接)→ 连接池复用 TCP 连接 → 协议编解码 → 网络 I/O → 响应解析/回调其核心优势在于「连接复用降低开销」「拦截器链易扩展」「多协议支持(HTTP/1.1/2/3)」,也是 Retrofit、Volley 等框架的底层网络实现,是 Android 网络开发的事实标准。

2025-12-16 23:00:11 958

原创 如何使用 OKHttp 实现 HTTP/2 多路复用?

默认启用:OKHttp 客户端无需额外配置,仅需服务端支持 HTTP/2;连接复用:并发执行多个请求时,OKHttp 会自动在单个 TCP 连接上创建多个流(Stream),实现多路复用;验证关键:通过「协议版本(h2)」「TCP 连接数(1 个)」确认生效;进阶优化:调整连接池、流优先级、并发数,最大化多路复用效率。只需保证「服务端支持 HTTP/2 + 客户端使用标准 OKHttp 配置」,即可零成本享受 HTTP/2 多路复用带来的性能提升(减少 TCP 握手开销、避免队头阻塞)。

2025-12-16 22:55:40 836

原创 如何在Android中使用StateFlow和MutableStateFlow?

推荐用data class封装 UI 状态,保证状态不可变(通过copy// 示例:页面加载状态val isLoading: Boolean = false, // 加载中= null, // 业务数据= null // 错误信息组件作用核心类ViewModel持有状态、处理业务逻辑MutableStateFlow (私有)对外暴露提供只读状态供 UI 层收集StateFlow (公开)UI 层收集状态、更新 UI。

2025-12-16 18:15:34 593

原创 StateFlow 和 MutableStateFlow 有什么区别?

特性StateFlow可变性只读(仅能收集状态,无法修改值)可变(可修改状态值,继承自StateFlow核心能力暴露状态、供订阅者收集修改状态值(value可读写)、发送状态变更构造方式无法直接实例化,需通过转换直接实例化(必须传入初始值)对外暴露推荐作为公开 API 暴露给外部(如 ViewModel 对外提供)仅私有持有(避免外部直接修改状态)维度StateFlow角色只读视图(对外暴露)可写实现(内部持有)核心操作收集状态、读取 value修改 value、发送状态变更。

2025-12-16 17:57:11 756

原创 StateFlow

StateFlow通常通过实现可变状态,对外暴露只读的StateFlow// 定义状态数据类(推荐封装状态)= null// 持有可变 StateFlow// 对外暴露只读 StateFlowStateFlow是 Kotlin 协程中针对单一、可观察状态设计的核心组件,结合协程生命周期管理,是 Android MVVM 架构中状态管理的首选方案。其核心优势是简洁的状态持有、自动过滤重复值、线程安全,能高效解决 UI 状态同步问题。

2025-12-16 17:54:07 364

原创 LeakCanary 检测内存泄漏的核心原理

避免 LeakCanary 误报的核心是「精准配置过滤规则 + 规范代码中的引用持有」通过过滤系统缓存、第三方库等合法引用;优先使用Context,避免ActivityContext 被长生命周期对象持有;及时清理Handler延迟任务、回调引用,使用弱引用包装临时对象;结合引用链分析和复现验证,区分真泄漏和误报。监听生命周期 → 弱引用+引用队列标记 → 延迟+多次GC验证 → 堆转储 → 分析GC Root引用链 → 报告泄漏。

2025-12-15 23:25:26 784

原创 LeakCanary如何避免误报内存泄漏?

避免 LeakCanary 误报的核心是「精准配置过滤规则 + 规范代码中的引用持有」通过过滤系统缓存、第三方库等合法引用;优先使用Context,避免ActivityContext 被长生命周期对象持有;及时清理Handler延迟任务、回调引用,使用弱引用包装临时对象;结合引用链分析和复现验证,区分真泄漏和误报。

2025-12-15 23:10:44 833

原创 如何在Android中使用RemoteCallbackList?

服务接口(供客户端调用注册 / 解注册)和回调接口(服务端向客户端推送事件)。

2025-12-01 14:41:05 885

原创 在Kotlin中使用async和await时,如何控制并发协程的数量?

控制首选Semaphore:简洁、高效、异常安全,适用于大多数场景。需顺序执行用Channel:适合任务需按发送顺序处理的场景。严格分批用chunked:实现最简单,适合需避免瞬间高并发的场景。通过以上方案,可在 Kotlin 中优雅地控制协程并发数,避免资源耗尽,同时保持协程的异步优势。Kotlin 中使用Semaphore控制并发协程数量以下是Kotlin 中使用Semaphore控制并发协程数量的完整代码示例,包含基础用法、异常处理、Android 实际场景适配使用Semaphore。

2025-11-26 16:45:16 622

原创 如何在Kotlin中使用async和await来并发执行多个协程?

使用async和await在协程作用域中,通过async启动多个异步任务,获取对象。通过await()(单个任务)或awaitAll()(多个任务)获取结果(会挂起当前协程)。处理结果或异常,更新 UI 状态(如结合StateFlow核心优势并行执行任务,提升效率(总耗时取决于最慢任务)。挂起函数不阻塞线程,资源利用率更高。与 Kotlin 语法无缝集成,代码简洁易读。适用场景批量网络请求、数据库操作。并行计算(如多组数据解析)。独立资源加载(如图片、文件)。

2025-11-26 15:44:06 979

原创 如何使用协程和StateFlow处理数据的并发更新?

/ 1. 定义不可变的 UI 状态= null// 2. 定义用户意图// 数据模型在 ViewModel 中创建来存储你的 UI 状态。通过暴露一个不可变的StateFlow给 UI。使用来启动协程,处理所有耗时的并发任务(如网络请求)。在协程中,始终使用来修改状态。这个原子操作确保你总是基于最新的状态进行更新,从而避免并发冲突。UI 层通过(或类似的生命周期感知协程) 来收集uiState,并根据收到的最新状态渲染界面。

2025-11-26 11:44:51 619

原创 在MVI模式中,如何确保数据的一致性和完整性?

场景推荐方案核心优势简单并发状态更新(如列表增删)轻量、原子、无额外依赖复杂并发逻辑(如依赖前状态的更新)Mutex确保临界区原子执行,避免竞态条件大量并发请求(如快速点击)Channel序列化按顺序处理请求,避免重复操作持久化数据更新(如数据库操作)数据库事务(Room)确保持久化操作的原子性和一致性通过以上方案,可在 MVI 模式中优雅处理数据的并发更新,确保状态的一致性和安全性。

2025-11-26 11:37:08 648

原创 MVI模式

MVI 是一种非常强大和优雅的架构模式,特别适合构建复杂且状态多变的应用。它通过强制单向数据流和不可变性,让应用的状态管理变得简单、可预测和易于测试。虽然有一些初始的学习和代码成本,但从长远来看,它能极大地提高代码的质量和可维护性。创建数据类,代表需要持久化的数据。// 数据模型在 Model 层定义一个Repository 接口,封装持久化操作(如增删改查)。这样可以隔离具体的持久化实现(如 Room、SharedPreferences、Retrofit)。// 持久化仓库接口封装。

2025-11-26 11:26:47 761

原创 在androidStudio中如何通过 Heap Dump 分析内存泄漏

所有存活的对象对象的类型、大小对象之间的引用关系线程信息哪些对象占用了大量内存哪些对象本该被回收却没有被回收对象之间的引用链,找到内存泄漏的根源获取 Heap Dump:使用 Profiler 或代码手动生成。分析对象数量和大小:找出实例数量异常或 Retained Size 很大的对象。查找引用链:通过找到持有该对象的引用链。定位问题根源:分析引用链,找出不应该存在的强引用。修复问题:根据具体场景,使用 WeakReference、注销监听器、释放资源等方式修复内存泄漏。

2025-11-24 20:46:33 1127

原创 如何优化Glide图片加载库的性能?

Glide 性能优化的核心思路是“按需加载、减少冗余、复用资源”。在实际开发中,需要结合具体场景(如列表、大图、动态图)选择合适的优化方案,同时通过监控工具持续分析性能瓶颈,针对性优化。如何使用Glide的缓存策略?Glide 的缓存策略核心围绕内存缓存和磁盘缓存展开,合理配置缓存策略可以显著提升图片加载性能,减少网络请求和资源消耗。// 在 Application 初始化时配置// 设置为 10MB/sdcard/Android/data/[包名]/cache/glide/,可通过@Override。

2025-11-22 19:41:14 120

原创 Glide图片加载库的实现原理

Glide 的成功在于其高效的缓存策略、优秀的生命周期管理、灵活的扩展性以及对多种图片类型的良好支持。通过分层架构和模块化设计,Glide 能够在性能和易用性之间取得平衡,成为 Android 开发中图片加载的首选库之一。

2025-11-22 19:20:19 87

原创 如何使用 Glide 进行图片变换

如果 Glide 内置的变换无法满足需求,可以自定义。@Override// 创建一个新的 Bitmap// 创建画布和画笔// 设置颜色矩阵为灰度// 饱和度为 0,即灰度// 绘制灰度图片// 返回处理后的 Bitmap@Override// 更新磁盘缓存的 Key,确保缓存能正确失效Glide 提供了灵活且强大的图片变换功能,无论是使用内置变换、自定义变换还是第三方库,都能轻松实现各种图片处理效果。

2025-11-22 18:50:53 67

原创 图片加载库的缓存机制

三级缓存的核心价值是 “空间换时间”,适合数据重复访问率高、对加载速度敏感、网络环境不稳定的场景(如图片加载、列表数据缓存)。实际使用时,需通过合理配置缓存大小、过期策略、缓存键规则,平衡其优点与局限性,避免因配置不当导致的性能问题或数据不一致。图片加载库的缓存原理可概括为“三级缓存 + LRU 淘汰 + 唯一键标识”内存缓存负责 “快速响应”,磁盘缓存负责 “持久化与扩容”,网络 / 本地源负责 “原始获取”;通过合理的缓存策略,在速度、容量、一致性之间达到平衡,最终提升应用的图片加载体验。

2025-11-21 15:50:37 60

原创 使用线程池时需要注意哪些事项?

使用线程池时,核心是合理配置参数、规范生命周期管理、保证任务线程安全、妥善处理异常。需根据业务场景(IO 密集型 / CPU 密集型、任务数量、执行频率)灵活调整配置,避免滥用线程池导致的性能问题和资源浪费。如何根据业务场景合理配置线程池的核心参数?配置线程池的核心参数,本质上是在资源消耗和任务执行效率之间寻找一个最佳平衡点。明确任务类型:首先判断你的任务是 CPU 密集型还是 IO 密集型。以核心数为基准和的配置通常围绕 CPU 核心数展开。优先使用有界队列:避免使用无界队列带来的内存溢出风险。

2025-11-21 14:24:58 74

原创 Android 线程池的详细配置和使用

Android 线程池的核心是,其参数配置直接影响性能和稳定性。实际开发中,应根据业务场景(IO 密集型 / CPU 密集型、任务数量、执行频率)合理配置核心参数,避免使用Executors的默认实现,同时注意线程池的生命周期管理和异常处理。如果使用 Kotlin 开发,优先选择Coroutine(更简洁、高效);如果需要复杂的异步数据流处理,可考虑RxJava。

2025-11-21 11:10:57 113

原创 如何使用fastboot命令烧录镜像到开发板?

我们来详细梳理如何使用fastboot命令将编译好的 Android 镜像烧录到开发板。fastboot是 Android SDK 提供的一个非常强大的命令行工具,用于在设备的下与设备进行通信。这是一种比adb更底层的模式,通常用于刷机、解锁设备或烧录系统镜像。

2025-11-19 10:13:37 760

原创 如何启动编译好的系统镜像?

【代码】如何启动编译好的系统镜像?

2025-11-19 10:11:17 380

原创 在 Ubuntu 系统 上搭建 Android 源码(AOSP)环境 的步骤

至此,你已经成功在 Ubuntu 上搭建了 Android 源码环境并编译运行了自己的镜像。后续可以做什么?修改源码:尝试修改 framework 或应用层的代码,然后重新编译()并运行,验证你的修改。学习源码:使用 Android Studio 或其他 IDE 导入源码进行阅读和分析。编译特定模块:如果你只修改了某个特定模块(如Settings。

2025-11-19 10:04:03 769

原创 Windows10专业工作站版如何搭建Android源码环境?

Android 源码基于 Linux 内核,无法直接在 Windows10 环境编译,Windows10 专业工作站版搭建 Android 源码环境,最推荐通过搭建 Linux 环境来实现,该方式相比虚拟机更轻量化,资源占用少且操作便捷。

2025-11-19 09:55:48 616

原创 Android NDK 开发

定义:NDK 是 Android SDK 的补充工具集,用于将 C/C++ 代码编译成.so(Shared Object,共享库)文件,供 Android 应用(Java/Kotlin)调用。核心作用复用现有 C/C++ 代码(如算法库、游戏引擎、硬件驱动)。提升性能敏感场景(如实时渲染、音视频处理、加密计算)的执行效率。访问 Android 平台的底层 API(如 OpenSL ES 音频、OpenGL ES 图形、传感器)。适用场景高性能计算(如数学建模、图像处理)。

2025-11-17 11:41:52 951

原创 策略模式的具体实现

这个接口定义了所有支付方式都必须具备的核心行为 ——pay。/*** 支付策略接口*//*** 支付方法* @param amount 需要支付的金额* @return 支付结果信息*/策略模式的核心思想是“封装变化,委托执行”。封装变化:将不同的支付算法(变化点)封装在独立的策略类中(...)。委托执行:上下文类()持有一个策略接口的引用,它不关心具体是哪种策略,只负责调用策略的统一方法(pay优势代码清晰:避免了使用if-else或switch。

2025-11-14 14:38:36 381

原创 观察者模式的具体实现

这个接口定义了被观察者需要具备的核心能力:注册观察者、移除观察者、通知观察者。/*** 被观察者(Subject)接口*//*** 注册一个观察者* @param observer 要注册的观察者*//*** 移除一个观察者* @param observer 要移除的观察者*//*** 当主题状态改变时,通知所有注册的观察者*/这个接口定义了观察者的核心能力:接收并处理来自被观察者的通知。java运行/*** 观察者(Observer)接口*//**

2025-11-14 09:43:53 463

原创 Java设计模式

Java 设计模式是软件开发中的宝贵经验,它们提供了一套标准化的解决方案,帮助开发者解决常见的设计问题。掌握设计模式不仅可以提高代码的质量和可维护性,还可以提升开发者的设计能力和思维水平。

2025-11-13 17:36:15 840

原创 如何在AIDL中传递List和Map数据类型?

Parcelableimport是必须的:在 AIDL 文件中,无论ListMap还是自定义的Parcelable对象,都需要使用import语句引入。泛型是必须的这样的写法是强制要求,不能简单地写List或Map。元素必须是 AIDL 支持的类型:这是最容易出错的地方。如果List或Map中包含了一个没有实现Parcelable或没有在 AIDL 中声明的对象,编译会失败。方向标记:对于in,服务端会收到客户端数据的一份拷贝,服务端的修改不会影响客户端。对于out。

2025-11-13 11:16:59 931

原创 如何在AIDL中传递复杂的数据类型?

如何在AIDL中传递复杂的数据类型?

2025-11-12 14:41:33 703

原创 如何在AIDL中使用Parcelable?

ParcelableAIDL 无法直接识别 Java 类,需通过.aidl文件显式声明 “该类型是可跨进程传递的Parcelable对象”。假设需要实现 “根据用户 ID 查询用户信息” 的跨进程方法,需在业务 AIDL(如用import导入自定义类型的 AIDL(即使在同一个包下,也建议显式导入);直接将自定义类型作为方法的参数或返回值。自定义类实现Parcelable(序列化 / 反序列化逻辑 +CREATOR创建同名.aidl文件声明该类型;

2025-11-12 11:42:42 801

原创 如何使用Binder通信技术?

运行服务端:将你的应用安装到手机或模拟器上。启动,点击 "绑定服务" 按钮。观察 Logcat:你会看到打印出 "Service bound by client." 的日志。调用方法:点击 "调用服务方法" 按钮。客户端会通过 Binder 调用服务端的add方法,并显示结果 "10 + 20 = 30"。服务端的 Logcat 也会打印出收到的参数。解绑服务:点击 "解绑服务" 按钮,连接断开。通过以上步骤,你就成功地实现了一次基于 Binder (AIDL) 的跨进程通信。

2025-11-12 10:41:21 511

原创 Binder通信技术、IPC通信机制‌

特性IPC (通用概念)Binder (Android 实现)定义进程间通信的统称。Android 系统中实现 IPC 的一种具体技术和机制。范围广义,包含多种实现方式(管道、Socket、Binder 等)。狭义,是 IPC 的一种。核心组件因实现方式而异。通信模型多样。C/S (客户端 / 服务器) 模型。性能取决于具体实现(如 Socket 较慢)。很高,一次数据拷贝。安全性取决于具体实现(如 Socket 不安全)。很好,基于 UID/PID 的权限校验。主要应用所有操作系统。

2025-11-12 10:30:49 745

原创 Android Studio 的 Profile使用

这是 Android Studio 的 Profiler 工具界面,用于分析应用的性能(CPU、内存、系统活动等)。

2025-11-12 09:00:40 786

原创 如何解读Profiler中的内存监控图表?

内存监控图表是 Profiler 中最直观的部分,它像一张 “心电图”,反映了应用在运行时的内存健康状况。解读它,主要关注三个核心维度:趋势、波动和异常点。

2025-11-09 17:14:48 918

原创 如何使用Profiler进行内存分析?

先观察,后分析:不要一上来就抓取快照。先通过实时监控观察内存趋势,发现异常模式后再进行深入分析。多次快照,对比分析:这是发现内存泄漏的最可靠方法。理解 Retained Size:这是衡量一个对象 “重量” 的关键指标。一个对象即使自身很小,但如果它引用了一个庞大的对象树,它的也会非常大。精通 References 视图:这是找到内存泄漏 “元凶” 的终极手段。要能看懂引用链,区分强引用、软引用、弱引用和虚引用。结合 Allocation Tracking。

2025-11-08 23:17:28 740

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除