- 博客(132)
- 收藏
- 关注
原创 Compose Canvas 中添加手势控制
本文详细介绍了如何在Jetpack Compose中利用Canvas和手势控制创建交互式绘图应用。主要内容包括:1)基础手势集成,通过detectDragGestures、detectTransformGestures实现拖拽、缩放和旋转;2)复杂交互实现,如拖拽绘制对象和视图变换;3)手势控制绘图应用开发,包括路径绘制和状态管理;4)手势控制图表交互的实现方法;5)高级技巧包括手势冲突解决、性能优化和形状识别。文章强调通过mutableStateOf管理状态,使用drawWithCache优化性能,并演示
2025-06-15 12:03:25
315
原创 Jetpack Compose Canvas 深度解析
Jetpack Compose的Canvas组件采用声明式方式实现2D绘图,支持绘制基本形状(矩形、圆形、线条等)、路径(贝塞尔曲线)、图像和文本,并提供坐标变换、渐变填充等高级功能。开发者可通过DrawScope扩展函数复用绘图逻辑,结合动画系统实现动态效果。最佳实践包括:避免绘制块内创建对象、使用drawWithCache优化性能、限制重绘区域。Canvas还支持构建交互式绘图板,通过手势检测实现用户绘制功能。该组件既保留了传统Android Canvas的核心能力,又融合了Compose的响应式特性,
2025-06-15 11:44:04
224
原创 Jetpack Compose -> pointerInput 处理手势的核心
/ 实现滑动方向检测drag?.let {when {horizontal -> println("水平滑动")vertical -> println("垂直滑动")
2025-06-15 11:32:43
507
原创 Android Jetpack 组件库 ->Jetpack Navigation
Jetpack Navigation 通过声明式导航图类型安全传参和深度 UI 集成,显著简化了复杂导航逻辑的开发,尤其适合单 Activity 架构。其可视化工具和标准化 API 降低了维护成本,是构建现代 Android 应用的首选导航方案。Jetpack Navigation 官方文档。
2025-06-12 15:07:36
713
原创 Jetpack LiveData 深度解析
LiveData是Android架构组件中的核心类,具有生命周期感知能力,能自动管理UI数据更新。其优势包括:自动处理观察者生命周期以避免内存泄漏,在配置更改时保持数据,保证UI一致性。基本用法包括创建MutableLiveData对象,通过ViewModel暴露只读LiveData,并在Fragment中观察数据变化。进阶功能支持数据转换、协程集成和事件处理等。测试时可用InstantTaskExecutorRule或自定义TestObserver。最佳实践建议:ViewModel中只暴露LiveData
2025-06-12 14:55:46
955
原创 Kotlin 协程与 ViewModel 的完美结合
Kotlin 协程与 ViewModel 的结合为 Android 开发提供了强大的异步处理能力:使用确保协程生命周期与 ViewModel 一致结合StateFlowSharedFlow实现响应式 UI遵循单一职责原则,分离业务逻辑采用结构化并发简化错误处理和资源管理掌握这些技术将使你能够构建更加健壮、高效且易于维护的 Android 应用程序。
2025-06-12 13:17:34
752
原创 Jetpack 架构组件 -> ViewModel
Android ViewModel是Jetpack的核心组件,用于以生命周期感知的方式管理UI数据。它能解决数据持久化(屏幕旋转时保留数据)、防止内存泄漏、实现UI与数据分离等痛点。使用时需先添加依赖,创建继承ViewModel的类,然后在Activity/Fragment中通过ViewModelProvider获取实例。关键特性包括:比Activity更长的生命周期、配合LiveData使用、支持参数初始化、Fragment间数据共享。最佳实践包括不持有Context、保持轻量化、结合Repository
2025-06-12 12:56:18
983
原创 OkHttp 中实现断点续传 demo
OkHttp实现断点续传的核心是通过HTTP Range请求头指定下载范围。主要步骤包括:1)获取已下载字节数;2)创建带Range头的请求;3)检查服务器是否支持断点续传(206状态码);4)使用RandomAccessFile从断点追加写入文件;5)实时更新下载进度。关键点在于处理Range请求、文件随机访问和进度跟踪,需注意服务器支持检查和异常处理。该方案可有效提升大文件下载体验,支持网络中断后自动恢复。
2025-06-10 22:17:58
402
原创 多场景 OkHttpClient 管理器 - Android 网络通信解决方案
下面是一个完整的 Android 实现,展示如何创建和管理多个 OkHttpClient 实例,分别用于长连接、普通 HTTP 请求和文件下载场景。
2025-06-10 22:15:10
598
原创 okhttp 实现长连接的完整方案
OkHttp 天然支持 HTTP/1.x 的 Keep-Alive 和 HTTP/2 的多路复用,可以高效实现长连接通信。
2025-06-10 22:12:50
626
原创 创建多个 OkHttpClient 实例 场景
在 Android 开发中使用 OkHttp 时,创建多个 HttpClient 实例通常是为了满足不同的网络请求需求。
2025-06-10 21:54:08
905
原创 Android 中使用 OkHttp 创建多个 Client
在 Android 开发中,有时我们需要创建多个 OkHttpClient 实例来满足不同的网络请求需求。
2025-06-10 21:52:45
586
原创 Hilt 和 AOP(面向切面编程) 关系
想象 Hilt 是负责精确组装机器各个零部件的工厂(依赖注入),而 AOP 是给组装好的机器某些部位统一喷漆(日志)、加装保护罩(权限)或者安装传感器(监控)的流水线(横切关注点)。工厂(Hilt)本身不负责喷漆,但它组装出来的零件可以被送到喷漆流水线(AOP)处理,或者工厂也可以自己先给某些零件简单喷一下(用 Hilt 模拟简单 AOP)。Hilt 和 AOP(面向切面编程)是解决不同领域问题的技术,但它们可以在 Android 开发中协同工作,有时甚至可以达到相似的效果(特别是在处理横切关注点方面)。
2025-06-09 18:03:27
701
原创 Hilt vs Dagger2:Android 依赖注入框架对比
Hilt是Dagger2的Android优化版本,两者核心差异在于易用性。Hilt简化了依赖注入配置,通过注解自动处理Android组件(如@AndroidEntryPoint),大幅减少样板代码;而Dagger2需要手动管理Component和生命周期。Hilt深度集成Jetpack,提供标准化组件,适合新项目;Dagger2则更适用于需要精细控制或非Android项目。性能相当,但Hilt开发效率更高,推荐新项目优先采用,现有Dagger2项目可逐步迁移。
2025-06-09 18:00:23
424
原创 Dagger 2 原理和使用
Dagger2是一个编译时依赖注入框架,通过注解处理器在编译时生成依赖管理代码。其核心机制包括:@Inject标记依赖需求与提供者,@Module/@Provides定义依赖创建逻辑,@Component作为依赖提供与使用的桥梁。Dagger2的优势在于编译时验证依赖关系、无反射开销、代码可追溯性,并支持复杂依赖管理、模块化开发、测试优化等场景。在Android开发中特别适合处理生命周期绑定、作用域管理等平台特性,相比运行时DI框架具有显著的性能优势。
2025-06-09 17:55:45
614
原创 Hilt -> Android 专属依赖注入(DI)框架
Hilt是Google推出的Android专属依赖注入框架,基于Dagger二次封装,简化了依赖管理流程。其核心优势包括:自动生成组件和作用域、内置Android类支持、生命周期管理以及与Jetpack组件深度集成。使用步骤包含添加依赖、初始化Hilt、声明依赖提供方式和注入依赖。Hilt通过预定义组件(如SingletonComponent、ActivityComponent)管理依赖生命周期,并提供了与ViewModel、Room等Jetpack组件的集成方案。常见问题包括私有字段注入限制和作用域冲突等
2025-06-09 17:38:26
829
原创 AspectJ 在 Android 中的完整使用指南
《Android AspectJ实战指南》摘要:本文详细介绍了AspectJ在Android中的配置与使用。环境配置部分重点说明Gradle7.0+的适配方案,推荐使用官方io.freefair.aspectj插件。核心内容包括切点表达式语法和五种通知类型的使用方法。实战案例展示了自动日志追踪和权限自动申请的实现。针对常见问题提供织入失效排查方案,并给出性能优化建议,如精确限定切点范围。对比分析了AspectJ与其他AOP方案的优劣,指出AspectJ仍是功能最完备的选择。最后通过支付参数加密示例,展示了编
2025-06-09 17:19:18
565
原创 AOP:面向切面编程详解
虽然引入会带来一定的构建复杂度和学习成本,但对于需要处理日志、权限、埋点、性能监控等通用逻辑的项目来说,收益是巨大的。这些是散布在应用多个模块中的功能(如日志、权限检查、性能监控、事务管理等),与核心业务逻辑无关,但又是必需的。轻松实现一些难以通过传统 OOP 实现的功能,如无痕埋点、全局性能监控、自动重试等。将分散在各处的通用逻辑(如日志、权限)集中到切面中,避免代码重复和侵入性修改。:程序执行过程中的特定点(例如方法调用、方法执行、构造器调用、字段访问)。学习曲线陡峭,开发复杂,容易出错,调试困难。
2025-06-09 16:30:55
1256
原创 DI是IoC的关系
摘要:IoC(控制反转)是一种设计原则,强调将控制权交给外部容器以实现解耦;DI(依赖注入)是实现IoC的主要技术手段,具体通过容器将依赖对象注入到需要它们的对象中。IoC关注控制权的转移,而DI则解决依赖关系的提供方式,如构造函数注入或Setter方法注入。简单来说,IoC是目标(解耦),DI是达成该目标的具体方法(注入依赖)。现代框架如Spring通过DI技术实现了IoC原则。
2025-06-09 16:05:10
505
原创 依赖注入(Dependency Injection)
组件只依赖于抽象(接口),不依赖于具体实现。可以轻松地用 Mock 对象或 Stub 对象(实现相同接口)替换真实的依赖进行单元测试。代码更清晰、更模块化。修改一个组件的实现或其依赖项变得更容易,影响范围更小。解耦后的组件更容易被复用在不同的上下文中。容器集中管理对象创建和依赖关系,配置更清晰。鼓励面向接口编程和单一职责原则。依赖注入是一种通过将对象的依赖关系交由外部容器管理和注入来实现解耦的设计模式。
2025-06-09 16:02:31
1182
原创 val viewModel: CounterViewModel = viewModel() 和 val myViewModel = viewModel<XXXViewModel>() 什么区别
在 Jetpack Compose 中,和本质上是,只是写法上的差异。它们的核心作用都是。
2025-06-09 11:43:02
356
原创 Jetpack Compose 与 ViewModel 的完美结合
ViewModel 作为状态容器:管理 UI 状态和业务逻辑响应式状态更新:使用 StateFlow/LiveData + collectAsState 实现自动刷新单向数据流:确保状态变化的可预测性和可维护性生命周期感知:自动处理配置更改和资源清理依赖注入支持:通过 Hilt 简化依赖管理遵循这些模式和实践,你可以构建出结构清晰、可维护且高效响应的 Compose 应用。
2025-06-09 11:40:11
727
原创 Jetpack Compose 中的 produceState 详解
produceState是Jetpack Compose管理异步状态的核心API,它能将非Compose状态转换为可观察状态。主要特点包括:在组合中启动协程作用域、自动生成可变状态、管理协程生命周期。典型应用场景包括:异步数据加载(配合密封类处理不同状态)、Flow数据收集、定期刷新数据(如股票行情)和监听外部事件(如位置更新)。最佳实践建议使用key参数跟踪依赖项变化,配合ViewModel分离逻辑,并通过awaitDispose清理资源。相比remember,produceState内置协程支持,更适合
2025-06-09 11:07:55
353
原创 Android Firebase 推送问题排查指南
摘要:Firebase推送通知在Android设备失效可能由多种原因导致。常见问题包括设备未正确注册FCM、服务器配置错误、应用权限缺失、系统后台限制或Firebase服务未启用。解决方案涵盖验证设备令牌获取、检查服务器请求格式、补全权限声明、创建通知通道及启用FCM服务。调试时可查看令牌获取日志、分析服务器响应,并通过Firebase控制台发送测试消息。特殊场景需考虑网络状态、省电模式限制,中国区设备还需关注Google Play服务或华为HMS的兼容性问题。(149字)
2025-06-08 21:39:19
1290
原创 Android 集成 Firebase 指南
Android应用集成Firebase完整指南:1) 准备Android项目;2) 创建Firebase项目;3) 注册Android应用并下载配置文件;4) 配置Gradle添加插件和所需服务;5) 同步项目并初始化Firebase。支持核心功能、分析、认证、云存储等模块集成,提供一站式移动开发解决方案。
2025-06-08 21:35:50
1098
原创 compose 组件 ---无ui组件
Jetpack Compose中存在多种不参与UI渲染但功能重要的组件,主要包括状态管理组件(如remember、ViewModel)、副作用处理器(如LaunchedEffect、DisposableEffect)、布局逻辑组件和纯逻辑组合函数。这些无UI组件实现了业务逻辑与UI渲染的解耦,提高了代码复用性和可测试性。典型应用包括状态托管和副作用封装,相比传统开发方式更简洁高效。使用时需注意避免过度拆分和性能优化,合理运用这些组件能构建更清晰的Compose应用架构。
2025-06-07 22:48:16
626
原创 Android 蓝牙通信
Android蓝牙开发概要 Android平台支持传统蓝牙和低功耗蓝牙(BLE)两种通信方式。传统蓝牙适合大流量传输(如音频/文件),使用RFCOMM等协议;BLE适合间歇性小数据传输,功耗低,常用于健康设备和传感器。开发需配置蓝牙权限(包括Android 6.0+的位置权限和12+的扫描/连接权限),并声明蓝牙硬件功能。两种蓝牙方式各有适用场景,开发者应根据需求选择合适的通信方案。
2025-06-07 22:35:58
516
原创 Android USB 通信开发
Android USB 通信开发主要涉及两种模式:主机模式(Host Mode)和配件模式(Accessory Mode)。以下是开发USB通信应用的关键知识点和步骤。
2025-06-07 22:20:22
465
原创 Android和硬件通信
串口通信:Android 串口通信-CSDN博客蓝牙通信:Android 蓝牙通信-CSDN博客Android USB 通信:Android USB 通信开发-CSDN博客
2025-06-07 22:19:17
519
原创 Jetpack Compose 中,DisposableEffect、LaunchedEffect 和 sideEffect 区别和用途
Jetpack Compose中处理副作用的核心API对比:LaunchedEffect用于协程任务,自动取消;DisposableEffect管理需清理的资源,需手动释放;SideEffect适用于重组后的状态同步。三者分别针对异步操作、资源释放和状态更新场景,开发者应根据需求选择合适API以避免性能问题和内存泄漏。关键区别在于触发时机和清理机制,合理使用能有效管理Compose组件中的副作用。
2025-06-07 21:21:35
903
原创 协程的常用阻塞函数
这些函数会阻塞线程,导致其他任务无法在同一线程上执行。val clientSocket = serverSocket.accept() // 阻塞直到有客户端连接。val data = inputStream.read() // 阻塞直到读取到数据。val result = future.get() // 阻塞直到任务完成。Thread.sleep(1000) // 阻塞线程 1 秒。latch.await() // 阻塞直到计数器为 0。从输入流中读取数据时会阻塞,直到有数据可用或流结束。
2025-06-07 21:10:38
393
原创 Gradle 7.0 及以上版本集中管理项目依赖项的版本号、插件版本和库坐标
是的一个配置文件,用于集中管理项目依赖项的版本号、插件版本和库坐标。它采用(Tom's Obvious, Minimal Language)格式,是 Gradle 7.0 及以上版本引入的功能。:避免在多模块项目中重复定义版本号。:修改依赖版本时只需修改一处。:在 IDE(如 Android Studio)中提供自动补全。通常位于项目的gradle。
2025-06-07 20:55:53
377
原创 android NDK 的 -> 是什么意思
(也称为箭头运算符),它用于通过指针访问对象的成员函数或成员变量。用于通过指针访问其指向对象的成员(类似于。用于直接访问对象的成员,而。
2025-06-03 09:25:20
241
1
原创 JNIEnv (Java Native Interface Environment)
是 JNI (Java Native Interface) 中的一个核心概念,它是本地代码(如 C/C++)与 Java 虚拟机(JVM)交互的桥梁。
2025-06-03 09:03:10
251
原创 Kotlin 中 companion object 扩展函数和普通函数区别
Kotlin中companion object扩展函数与普通函数的主要区别在于:定义位置不同(类外部/内部),调用方式(通过类名/实例调用),访问权限(仅伴生对象成员/全实例成员/仅公有成员)。companion object扩展函数适用于静态工具方法和工厂模式,普通成员函数用于实例行为封装,普通扩展函数则为已有类添加功能。选择依据是是否需要直接通过类名调用或依赖实例状态。
2025-06-02 22:48:16
792
原创 Kotlin 中companion object {} 什么时候触发
Kotlin中companion object的初始化时机详解:伴生对象在首次实际访问类时触发初始化,包括访问伴生成员、创建实例或反射访问。与Java静态块不同,它采用懒加载机制,更灵活且线程安全。使用时需注意避免重型操作和循环依赖,建议用by lazy延迟初始化。典型场景中,仅类型声明不会触发初始化,而实际访问才会。该特性适合存放类常量、工厂方法等共享资源,但需合理设计以避免性能问题。
2025-06-02 22:43:43
646
原创 Kotlin 中 companion object 扩展函数详解
Kotlin的companion对象扩展函数允许为类的伴随对象添加新功能,类似于静态方法。通过fun ClassName.Companion.func()语法定义,可直接通过类名调用。这种扩展适用于添加工具方法、扩展第三方类或构建DSL,需注意companion对象必须存在且不会覆盖原有方法。典型应用场景包括验证函数、库扩展等,既能保持代码整洁,又能增强类功能。
2025-06-02 22:37:18
641
原创 Kotlin 中的 companion object 使用指南
是 Kotlin 中一个非常有用的特性,它允许你在类内部定义一个伴随对象,这个对象与类本身相关联(类似于 Java 中的静态成员,但更强大)。主要特点替代静态成员:可以命名:实现接口:扩展函数:与 Java 互操作Kotlin 的 成员在 Java 中可以通过 访问:如果你想在 Java 中像静态成员一样使用,可以添加 注解:这样在 Java 中就可以直接调用 。工厂方法:常量定义:单例模式:注意事项 在类加载时初始化(类似于
2025-06-02 22:21:52
512
原创 Kotlin 扩展函数详解
扩展函数是Kotlin中一项非常强大的特性,它允许你为现有的类添加新的函数,而无需继承该类或使用设计模式如装饰器模式。
2025-06-02 22:09:30
628
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人