- 博客(949)
- 资源 (2)
- 收藏
- 关注
原创 (Fragment六)ViewPager2 与 Fragment 结合时,FragmentStateAdapter 和 FragmentAdapter 的区别?它们的生命周期有何不同?
总结来说,和的核心区别源于它们对Fragment实例的销毁策略不同,这直接导致了生命周期的巨大差异和不同的适用场景。销毁实例,保存状态,用CPU时间换内存空间,适用于页面多、内存敏感的场景。保留实例,牺牲内存,用内存空间换切换速度,适用于页面少、体验要求极致的场景。我们通过对业务特性的精准分析来做出选择,确保在提供流畅用户体验的同时,也能保证应用的稳定性和低内存占用,这正是高级开发者需要具备的架构权衡能力。
2025-11-23 13:38:59
24
原创 (Fragment五)Fragment的 setArguments 为什么是必须的?直接通过构造函数传参会有什么问题?
总而言之,之所以是‘必须’的,是因为它完美地契合了Android系统对组件生命周期和状态管理的底层设计。它将Fragment的‘初始参数’这一概念,从普通的构造函数参数提升为了系统可识别、可管理、可持久化的一部分状态。这使得Fragment能够安然无恙地度过配置变更和进程恢复等系统事件,保证了数据的一致性和应用的健壮性。而直接通过构造函数传参,则是一种与系统重建机制背道而驰的‘硬编码’方式,必然会在这些场景下导致崩溃或数据丢失。我们将正确使用。
2025-11-23 13:35:17
19
原创 (Fragment四)add + show/hide 和 replace 两种方案在生命周期和视图状态上有何不同?如何选择?
总而言之,addshow/hide和replace的选择是一场“空间换时间”的经典权衡。追求极致流畅和状态保留,用addshow/hide:它通过将Fragment及其视图常驻内存,换来了毫秒级的切换速度和完美的状态一致性。这是实现高端用户体验的利器,但需要开发者具备精细的内存管理意识。追求内存效率和清晰的线性流程,用replace:它保证了任何时候容器内只有一个活跃的Fragment,内存占用干净,但牺牲了切换性能和状态自动保留。在复杂业务中,我们通常会混合使用这两种策略。对核心主框架采用。
2025-11-23 13:22:03
24
原创 (View体系三)自定义View如何正确处理 wrap_content 和 padding?
总结来说,要正确处理好和padding对于:在onMeasure中,必须根据View的内容计算出期望尺寸,并使用方法结合父View的MeasureSpec(特别是AT_MOST模式)来确定最终尺寸。对于padding在onMeasure阶段,如果View尺寸包裹内容,那么总尺寸应该是内容尺寸 + padding。在onDraw阶段,所有内容的绘制起始位置和边界都必须考虑padding值,确保内容绘制在可用的内容区域内。在开发规范中,一个不处理和padding。
2025-10-21 00:48:12
350
原创 (View体系二)MeasureSpec 的三种模式(EXACTLY, AT_MOST, UNSPECIFIED)?
一个健壮的自定义View必须在onMeasure中正确处理这三种模式。kotlinval desiredWidth = calculateDesiredWidth() // 计算内容需要的宽度val desiredHeight = calculateDesiredHeight() // 计算内容需要的高度// 实际上,我们可以使用View提供的工具方法,它内部逻辑如下:MeasureSpec.EXACTLY -> size // 必须用父View给的尺寸。
2025-10-21 00:42:56
818
原创 (View体系一)View的测量(Measure)、布局(Layout)、绘制(Draw)流程的完整细节?
测量流程自顶向下递归。父View通过将约束传递给子View,子View通过onMeasure确定自己的尺寸。核心是解决‘有多大’的问题。布局流程自顶向下递归。父View根据测量结果和布局规则,在onLayout中确定所有子View的位置。核心是解决‘在哪里’的问题。绘制流程自顶向下递归。每个View在onDraw中绘制自己,ViewGroup在中委托子View绘制。核心是解决‘长什么样’的问题。减少测量深度:扁平化的View层级能显著减少onMeasure的递归调用次数。避免无效绘制:通过。
2025-10-21 00:38:15
646
原创 (Fragment三)Fragment之间通信的最佳实践(ViewModel、接口回调)?
首选且作为基石的,是共享ViewModel。它用于处理所有需要持久化、需要观察的状态数据。这提供了最好的解耦、生命周期安全和可测试性。谨慎使用接口回调,仅将其用于通知宿主Activity执行其职责范围内的单一、无状态动作(如‘打开某个页面’、‘更新工具栏’),并且必须注意在onDetach中解注册。对于一次性事件,我们会使用经过包装的‘单次事件流’,例如SharedFlow配置replay=0,以避免在配置变更后事件重放的问题。
2025-10-21 00:28:02
932
原创 (Fragment二)Fragment的add 和 replace 的区别?Fragment回退栈的工作原理?
总结一下,add和replaceadd是叠加,replace是替换。在单内容区域的导航中,我们几乎总是使用replace。而回退栈的工作原理,可以理解为一部记录用户操作步骤的‘历史纪录片’。每当我们进行一次,就为这部纪录片增加了一个片段。按下返回键,就像是倒放这部纪录片,系统会精确地逆向执行每一个操作,将UI状态恢复到之前的样子。在开发实践中,我们通常会基于replace来构建单Activity多Fragment的导航架构。同时,我们会严格在。
2025-10-21 00:23:02
709
原创 (Fragment一)Fragment的生命周期如何与Activity联动?
总而言之,Fragment的生命周期是Activity生命周期的精细投影,二者紧密耦合。这种联动关系要求开发者必须清晰地知道在哪个Fragment回调中执行何种操作是安全的。视图初始化在中完成。数据初始化和观察在中进行,并利用LifecycleOwner自动管理订阅生命周期。视图引用清理在中完成,这是防止内存泄漏的生命线。使用ViewModel来持有数据,完美解耦数据与UI的生命周期,并优雅地处理配置变更。
2025-10-21 00:16:59
567
原创 (Activity三)屏幕旋转时Activity生命周期的完整流程?如何防止数据丢失?
临时UI状态:使用保存到Bundle,这是一个轻量级的‘急救包’。核心UI数据:使用ViewModel,这是现代Android架构的基石,它能优雅地在配置变更中存活,是解决此问题的首选和主流方案。永久性数据:使用持久化存储(如 Room、SharedPreferences),这是数据的最终归宿。在开发实践中,我们严格遵循 Android Jetpack 的架构指南。对于屏幕旋转这类配置变更,我们几乎总是使用的组合来管理UI数据,这不仅完美地解决了数据丢失问题,还实现了关注点分离,让代码更易于测试和维护。
2025-10-19 02:35:26
913
原创 (Activity二)onNewIntent() 方法的调用时机?
总而言之,在singleTopsingleTask这三种启动模式下,当系统决定复用现有 Activity 实例而非创建新实例时。它的出现,意味着 Activity 经历了一次‘重生’,并被赋予了新的‘使命’(新的 Intent)。作为开发者,我们的职责就是在中必须调用来更新数据,并重新处理这个新的 Intent,以确保 UI 和状态与最新的意图保持一致。在复杂业务场景中,例如处理推送消息、深度链接跳转、或者在单 Activity 架构中管理多个 Fragment,正确理解和运用。
2025-10-19 02:31:54
916
原创 (Activity一)启动模式(standard, singleTop, singleTask, singleInstance)的应用场景及对应的任务栈(Task)变化?
standard:就像在抖音里,每点开一个视频,就新开一个详情页窗口,用户可以逐个关闭。singleTop:就像用户已经在抖音首页(栈顶),这时收到一个推送,点进去还是那个首页,只是内容刷新了。singleTask:就像字节跳动的‘账号管理’中心,它是一个独立的功能模块(独立任务栈)。无论用户是从抖音、今日头条还是西瓜视频(不同任务栈)点击‘设置头像’跳转过来,都会直接进入这个中心。当在中心里完成修改后,按返回键,会直接回到原来跳转过来的App(原任务栈),而不是在中心里层层返回。:就像一个全公司。
2025-10-19 02:27:51
939
原创 (Java并发四)ConcurrentHashMap 在JDK1.7和1.8中如何保证线程安全?
特性JDK 1.7JDK 1.8核心思想分段锁锁粒度粗(一个Segment,包含多个HashEntry桶)极细(单个链表头/树根节点)数据结构Segment数组 + HashEntry数组 + 链表Node数组 + 链表/红黑树写操作对Segment加锁CAS(空桶)synchronized(非空桶)读操作无锁,依赖volatile完全无锁,依赖volatile与UnsafeHash冲突仅链表链表 +红黑树(优化极端情况)为什么1.8的方案更优?锁粒度更小。
2025-10-19 02:02:05
696
原创 (Java并发三)ThreadLocal 的原理和内存泄漏风险?
总结来说,的原理是利用了线程对象内部的哈希表()来为每个线程存储独立的变量副本,其访问入口是对象本身。而其内存泄漏风险是一个经典且必须重视的问题。根源在于的Key 是弱引用,而 Value 是强引用。当外部强引用被释放后,Key 会被GC回收,但 Value 由于线程生命周期的强引用而无法被回收,形成泄漏。在开发规范中,我们强制要求:将变量声明为,这不仅能避免重复创建,也明确了其生命周期与应用一致。在任何使用的代码块后,必须在finally块中显式调用remove()
2025-10-19 01:55:23
634
原创 (Java并发二)volatile 关键字的作用(可见性、禁止指令重排)?
总结来说,volatile关键字通过强制主内存读写和插入内存屏障,精准地解决了可见性和有序性这两个并发编程中的核心难题。然而,必须强调,volatile并不能保证原子性。一个经典的误区是认为然后count++是线程安全的。count++实际上是读-改-写三个操作的组合,volatile只能保证每次读都是最新的,写都是立即可见的,但无法阻止两个线程同时读到相同的值,然后各自加1再写回,从而导致更新丢失。因此,在开发实践中,我们对volatile的使用非常审慎:它适用于状态标志(如stopFlag。
2025-10-19 01:41:41
670
原创 (Java并发一)synchronized 的锁升级过程(无锁 -> 偏向锁 -> 轻量级锁 -> 重量级锁)?
总而言之,偏向锁是为无竞争场景开的‘绿灯’,几乎零开销。轻量级锁是为短时间竞争场景准备的‘CAS自旋’方案,避免了用户态到内核态的切换。重量级锁是处理激烈竞争的‘终极武器’,虽然开销大,但能保证在极端情况下的稳定性和公平性。在开发环境中,我们虽然很少需要直接干预这个过程,但深刻理解其原理至关重要。它解释了为何在低竞争情况下性能并不差,也提醒我们在高并发场景下,过度依赖可能导致性能瓶颈。这指引我们在设计高并发系统时,会更多地考虑使用包中更现代、更细粒度的并发工具,如等,来替代粗粒度的。
2025-10-19 01:34:18
783
原创 (Kotlin协程十八)supervisorScope 和 coroutineScope 在异常传播上有何不同?
总结来说,和体现了任务间的强依赖关系。一个任务的失败意味着整个并发操作的整体失败。适用于‘所有子任务都必须成功,整个操作才算成功’的场景,比如从多个源加载数据然后合并。体现了任务间的独立性。一个任务的失败不应影响其他不相关的任务。适用于‘后台任务集合’或‘UI 上的独立操作’,比如同时预加载多个不相关的图片,或者在一个页面中同时发起多个独立的网络请求。在开发实践中,我们会根据业务逻辑的语义来谨慎选择:如果子任务是一个不可分割的整体的一部分,用。如果子任务只是恰好一起启动但逻辑独立的‘任务组’,用。
2025-10-18 14:55:43
489
原创 (Kotlin协程十七)CoroutineExceptionHandler 的使用场景和局限性?
总结来说,作为全局兜底,防止未捕获的协程异常导致应用崩溃。与 SupervisorJob配合,在错误隔离的场景下集中处理个别任务失败。实现统一的错误上报和监控,为线上问题定位提供丰富上下文。其关键的局限性在于:作用域敏感:仅对根协程或的直接子协程有效。无法阻止取消:它处理的是异常发生后的结果,不能中断结构化并发的取消传播。对async无效async的异常需要通过await处的try/catch处理。非恢复机制:它用于通知和记录,而非错误恢复。在开发规范中,我们通常会定义一个全局的。
2025-10-18 14:50:23
528
原创 (Kotlin协程十六)try/catch 可以捕获子协程的异常吗?为什么?
总而言之,try/catch无法捕获launch协程的并发模型导致异常传播路径脱离了同步调用栈,转而遵循结构化并发的父子层级向上传播,最终由根协程或异常处理器处理。理解传播机制launch异常向上传播导致取消,async异常在await()时抛出。使用正确的工具对于launch,使用 CoroutineExceptionHandler(作用于根协程)或在协程内部使用try/catch。对于async,在调用await()的地方使用try/catch。使用 SupervisorJob。
2025-10-18 14:46:13
571
原创 (Kotlin协程十五)自己如何定义一个 CoroutineDispatcher?
在讨论如何实现之前,首先要明确为什么要这么做。:Android UI 线程:I/O 密集型任务:CPU 密集型任务与特定线程模型集成:需要将协程调度到特定的线程上,如一个单线程的数据库线程、一个自定义的事件循环线程、或一个 C++ 线程池。控制线程优先级:需要以特定的线程优先级(如) 来运行协程。限制并发度:需要创建一个并发数受限的专用线程池,例如同时只能有 2 个协程执行的"轻量级计算池"。监控与调试:在派发任务时注入监控逻辑,如记录执行时间、线程使用情况等。Kotlin 协程库提供了。
2025-10-18 14:41:27
502
原创 (Kotlin协程十四)如何将一个协程切换到另一个线程?withContext 的工作原理?
"所以,将一个协程切换到另一个线程,我们首选挂起函数。它的工作原理并非简单的线程跳转,而是一个基于协作式挂起与恢复挂起:在调用点挂起当前协程,释放底层线程。切换:由目标调度器(如)在另一个线程上执行代码块。恢复:执行完毕后,通过 CPS 机制和状态机,由原始调度器(如)在原始线程上恢复执行。线程安全:我们无需关心线程管理的细节。非阻塞:挂起不会阻塞原始线程,极大提升了并发效率。结构化:它完美融入了协程的结构化并发体系,异常取消都能正常传播。在高性能代码实践中,我们不仅要求会使用。
2025-10-18 14:37:39
464
原创 (Kotlin高级特性四)kotlin属性委托(如 by lazy) 的原理?
声明时,编译器创建一个实例,并将 Lambda存储其中。首次访问时检查_value,发现是。进入同步块,再次检查(Double-Check Locking)。执行 Lambda!(),得到结果"Kotlin"。将结果存入_value缓存,并清除引用。返回结果。后续访问时第一次检查_value发现已初始化,直接返回缓存的值"Kotlin",性能极高。by lazy只是标准库提供的委托之一,其他如observablevetoablemap委托,其原理完全相同,都是通过实现getValue。
2025-10-18 11:54:04
603
原创 (Kotlin高级特性三)Kotlin密封类(Sealed Class)在何时比枚举更适用?
总而言之,在 Kotlin 中选择密封类还是枚举,根本的决策依据是‘你需要的是不同类型的实例,还是同一类型的不同值’。当你需要定义的是一系列携带不同数据的、状态丰富的类型时,密封类是无可替代的工具。它在表达网络结果、UI 状态、命令模式、复杂语法树等场景下大放异彩,并与when表达式结合提供了无与伦比的类型安全和表达力。而当你只需要定义一组简单的、无状态的、单例的命名常量时,枚举则是更轻量、更直接的选择。在开发实践中,我们尤其看重代码的表达力和可维护性。在 MVVM 架构中,ViewState和。
2025-10-18 11:49:58
797
原创 (Kotlin高级特性二)kotlin内联函数(inline)的作用?为什么noinline和crossinline?
总结来说,inlinenoinline和是 Kotlin 为了在提供优雅的高阶函数特性的同时,解决其潜在性能和控制流问题而设计的一套精妙工具。inline是性能优化的利器,通过字节码展开消除函数调用和对象创建的开销,并附带开启了非局部返回的能力。noinline是灵活性的补充,它允许我们在内联函数中,将特定的 Lambda 当作普通的函数对象来使用,以满足存储或传递的需求。是安全性与契约的保障,它确保当 Lambda 在非直接调用上下文中被内联时,其控制流是局部且可预测的,防止了令人困惑的非局部返回行为。
2025-10-18 11:40:43
537
原创 (Kotlin高级特性一)kotlin的扩展函数和属性在字节码层面是如何实现的
总而言之,Kotlin 的扩展函数和属性是‘语法糖’的典范,它们通过编译器层面的巧妙转换,在兼容 JVM 字节码规范的前提下,为我们提供了更优雅的 API 设计能力。扩展函数被编译为静态方法,接收者对象作为第一个参数。扩展属性被编译为静态的 Getter/Setter 方法,并且没有幕后字段,其值完全由 Getter 函数计算。调试:当在调试器中单步执行扩展函数时,我们能理解为什么调用栈显示的是在一个工具类中。互操作:我们知道如何轻松地在 Java 代码中调用这些 Kotlin 扩展。没有魔法。
2025-10-18 11:28:12
892
原创 (Kotlin协程十三)Dispatchers.Main, IO, Default 分别适用于什么场景?它们的底层是什么?
是 UI 操作的唯一通道,其底层是主线程的Handler。是 CPU 算力的专用通道,其底层是大小固定的线程池,旨在榨干 CPU 性能。是 I/O 等待的高速公路,其底层是弹性伸缩的线程池,旨在支持高并发 I/O。在追求极致性能的工程实践中,我们要求开发者必须深刻理解这三者的区别。错误地将一个网络请求放在Default上,可能会占满宝贵的计算线程,导致真正需要计算的任务(如列表渲染)被阻塞,直接影响用户体验。反之,将一个复杂计算放在IO上,也是对资源的浪费。
2025-10-06 21:52:37
947
原创 (Kotlin协程十二)当一个父协程被取消时,它的子协程会怎样?
总结来说,父协程取消导致子协程全部取消,是 Kotlin 协程结构化并发的基石,它保证了资源不会泄漏,并提供了强大的生命周期管理能力。传播性:取消会沿着协程的父子层级树向下传播。协作性:子协程需要通过挂起函数或手动检查来响应取消信号。可控性:通过,我们可以控制异常的传播方向,实现错误隔离;而通过,我们可以临时‘突破’取消的限制,执行必要的最终操作。在 Android 开发实践中,尤其是在复杂的 UI 界面和 ViewModel 中,深刻理解并正确运用这一机制,是编写出健壮、稳定、无资源泄漏应用的根本。
2025-10-06 21:44:47
485
原创 (Kotlin协程十一)为什么说协程是“轻量级线程”
资源开销极‘轻’:用户态实现和动态栈使其内存占用远小于线程,允许大规模并发。切换效率极‘高’:用户态协作式切换避免了陷入内核的巨大开销,性能提升显著。编程模型更‘优’:它通过suspend函数和CPS+状态机的魔法,让我们可以用看似同步的代码写出高效的异步程序,彻底避免了‘回调地狱’。在追求极致性能和高并发的技术体系中,协程已经成为解决异步问题的基础设施。理解其‘轻量’的本质,意味着我们能够正确地使用它来构建出既能处理海量请求,又保持低资源消耗和高响应速度的现代化Android应用。
2025-10-06 10:46:59
764
原创 (Kotlin协程十)在大量创建协程时,如何通过CoroutineName和自定义CoroutineExceptionHandler来辅助调试和监控?
是用于处理在协程中未被捕获的异常的最后一道防线。核心问题:在launch构建的协程中,如果发生未捕获的异常,默认行为是:取消父协程及其同级协程(如果使用了则不会)。在线程的中处理异常。在Android上,这通常会导致应用崩溃。我们的目标:我们希望以一种更可控、更优雅的方式来处理这些异常,例如将错误信息上报到监控平台,而不是让应用直接崩溃。为所有业务协程命名:将作为创建协程时的标准配置。设置全局异常处理器:在应用的类中,创建一个包含和自定义的顶级,供整个应用使用。在处理器中利用协程名:在方法中,务必从。
2025-09-29 00:49:56
471
原创 (Kotlin协程八)Flow和RxJava的Observable在背压处理上有何异同?shareIn和stateIn操作符的作用是什么?
操作符输出类型核心用途典型场景shareInSharedFlow事件总线,多播数据流通知、导航事件、广播消息stateInStateFlow状态容器,持有当前状态UI状态(加载、成功、错误)、屏幕数据为什么使用它们?性能优化:避免为每个收集者都启动一次昂贵的操作(如网络请求、数据库查询),实现数据源共享。状态一致性:确保所有观察者看到的是同一个、最新的状态,避免数据不一致。架构整洁:在MVVM中,StateFlowstateIn是暴露UI状态的黄金标准,SharedFlowshareIn。
2025-09-29 00:37:35
911
原创 (Kotlin协程七)viewModelScope和lifecycleScope是如何实现自动取消的?它们的SupervisorJob设计是为什么?“
ViewModel通常承载着UI相关的多个数据请求。这些请求在业务逻辑上往往是独立的。一个请求的失败不应该导致整个屏幕的数据都无法加载。提供了这种错误隔离,使得应用的健壮性更强,用户体验更好。:在Activity/Fragment中,我们可能会启动多个用于UI操作的协程(例如,动画、表单验证等)。同样,这些操作也应该是独立的。一个动画的异常不应该导致整个页面的协程作用域被摧毁,从而影响其他正在进行的操作。结论和内部使用,是一种经过深思熟虑的、符合UI开发最佳实践的设计选择。
2025-09-29 00:21:21
594
原创 (Kotlin协程六)协程和RxJava的区别
总而言之,协程和RxJava的区别是“并发原语”与“响应式流库”的区别。协程解决了“如何更简单地写异步代码”的问题,它让并发编程回归简单和直观,是异步编程的“基础工具”。RxJava解决了“如何声明式和组合式地处理异步事件流”的问题,它是构建在异步编程之上的“高级抽象”。从技术趋势和工程效率来看,Kotlin协程是未来,也是当前Android异步编程的事实标准。它在绝大多数场景下提供了比RxJava更优的解决方案,特别是在启动成本、内存开销和代码可读性方面。
2025-09-28 23:08:33
894
原创 (Kotlin协程五)如何优雅地处理协程的取消和异常?
优雅处理协程取消和异常的精髓在于“协作”与“结构化”。取消:不是被动的等待,而是主动地通过yield()和让我们的代码成为“可取消的”,从而实现资源的即时回收和应用的快速响应。异常:要深刻理解launch和async不同的异常传播机制,并灵活运用try-catch以及来构建一个既健壮(不会崩溃)又符合业务逻辑(该取消的取消,该独立的独立)的异常处理体系。在字节跳动这样追求极致体验的应用中,这套严谨的处理机制是保证应用在高并发、复杂网络环境下依然稳定、流畅的基石。
2025-09-28 02:23:51
982
原创 (Kotlin协程四)协程上下文(CoroutineContext)由哪些元素构成?Dispatchers.IO 是如何工作的?
总而言之,是协程行为的配置中心,而是其高性能I/O调度的关键实现。它的设计体现了极高的资源利用效率:通过与Default调度器共享线程池,并根据I/O任务的阻塞特性弹性地扩展线程数,在保证性能的同时避免了资源浪费。对于字节跳动这样业务极其复杂的Android应用而言,深入理解并正确使用这些机制,是保证App在高并发I/O场景下依然保持流畅、稳定和低资源消耗的根本。这要求我们不仅会“用”协程,更要洞悉其内部的工作方式,从而做出最优的架构决策。
2025-09-28 02:19:00
898
原创 (Kotlin协程三)协程的挂起(suspend)原理是什么?(状态机)
总而言之,协程的挂起原理是Kotlin语言与编译器共同协作的一项杰作。它通过CPS变换和状态机,将看似同步的代码异步化,用顺序编程的思维解决了异步编程的难题。这不仅带来了代码可读性的巨大提升,更通过极低的开销实现了高效的并发。对于字节的Android开发而言,深入理解这一原理,意味着我们能真正驾驭协程这把利器,在面对复杂业务逻辑和高性能要求时,做出最合理、最可靠的技术决策,从而构建出用户体验更卓越的应用程序。
2025-09-28 02:14:40
430
原创 (Kotlin协程二)launch 与 async 的区别?Job 和 Deferred 是什么?
总结一下,launch和async目的不同launch侧重执行过程(Fire-and-forget),async侧重获取结果(Deferred result)。返回值不同Job用于控制生命周期,Deferred(继承自Job)用于获取结果。异常处理机制天差地别launch异常立即传播,容易导致作用域取消;async异常延迟传播,直到调用await()才触发。这是设计上的核心差异,也是为了支持并发场景所做的权衡。
2025-09-28 02:09:49
489
原创 (Kotlin协程一)协程的本质是什么?与线程的区别?
总而言之,协程的本质是Kotlin提供的一套以更低的成本、更优雅的方式解决异步编程问题的“线程上层框架”。它与线程的关系不是取代,而是增强和补充。在Android开发中,它通过挂起恢复、线程切换、生命周期绑定三大核心能力,将我们从繁琐的线程管理和回调陷阱中解放出来,让我们能够编写出更高性能、更健壮、更易维护的并发代码。这正是我们团队在构建复杂、高性能的Android应用时所迫切需要的技术。
2025-09-28 01:58:51
720
原创 Android高性能日志系统设计方案
本日志系统设计基于mmap内存映射技术实现高性能日志记录,支持日志本地存储和上传服务器、按时间段打捞日志,并自动管理15天内的日志存储。同时提供灵活的日志捞取机制。系统采用分层架构设计,包含日志采集层、缓冲层、存储层和上传层。本日志系统设计基于mmap实现高性能日志记录,
2025-04-25 01:19:18
545
原创 Android 一个单核CPU最多可以有多少个线程
在 Android 系统中,单核 CPU 可以创建的线程数量主要取决于操作系统限制和内存资源,而不是 CPU 核心数量本身。以下是详细分析:
2025-04-25 00:39:08
751
转载 Android的KeyStore保护数据
让我们先清除一些有关Android Keystore系统的知识。密钥库不一定只用于密码,它可以用于任何敏感数据,这样做的方式使攻击者或恶意/未经授权的软件很难从我们这里获取此信息。简单来说:应用程序只能编辑,保存和检索密钥。这个概念很简单,但功能强大。该应用将生成或接收私钥-公钥对,然后将其存储在Android Keystore系统中。然后,在将公用密钥存储在特定于应用程序的文件夹中之前,可以使用公用密钥对应用程序秘密进行加密,并在需要时使用专用密钥对相同信息进行解密。
2023-06-17 01:43:05
4335
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅