- 博客(34)
- 收藏
- 关注
原创 ForegroundNotificationService — startForeground 5s 超时 Crash 完整解决方案
每次调用都会触发一次5s计时器,调用次数越多,超时风险越高。运行中更新通知走,启动时用状态机防止重复入队,把的实际调用压缩到"服务真正需要启动"的那一次。
2026-04-27 10:08:24
199
原创 onSaveInstanceState() 生命周期与 setFragmentResult 回调问题分析
不会保存setFragmentResult结果,导致fragment 销毁重建时setFragmentResultListener收不到结果。(不保证一定会被销毁)Fragment 的。
2026-02-27 16:58:57
393
原创 Firebase DebugView 无法接收实时事件排查指南
无需每次连接电脑都重新设置,除非手机重启过。无论是修改了包名还是开启了日志,强杀进程是让配置生效的唯一可靠手段。如果后台“实时”模块有数据但 DebugView 没数据,重点检查setprop包名是否拼写正确以及浏览器页面是否需要刷新。不是必须的,为了看本地是否上传埋点, 在模拟器上使用FA过滤日志。
2026-01-23 11:47:47
623
原创 深度解析:从 AnimationHandler 原理看 Android 动画内存泄漏
如果你在自定义 View 中使用动画,利用@Override= null) {Android 动画内存泄漏的本质是“长生命周期的系统单例服务持有短生命周期的 UI 组件”。cancel()是核心:它是向发出“注销”信号的唯一有效方式。是源头:理解了单例驱动机制,就能明白为什么“看不见”的动画依然在消耗内存。养成在生命周期结束时手动cancel()动画的习惯,是每一位 Android 高级开发者的标准修养。
2026-01-16 11:27:02
667
原创 Task 生命周期与 baseIntent 使用分析
本文档分析当 Task 中最后一个 Activity finish 后,Task 的生命周期变化,以及重新启动 Activity 和从 Recents 恢复时 baseIntent 的使用机制。当用户调用↓↓代码位置if (intent!= null)?结论baseIntent就是字段。用户调用 Activity.finish()↓↓↓↓检查: hasChild() == false &&!↓调用 removeIfPossible()↓调用 removeImmediately()
2026-01-15 14:56:35
639
原创 Fragment View生命周期与动画回调导致的Crash修复
NonNull调用时机:只能在之后、之前检查条件= null失败原因mView为null或已被清空:Fragment已添加到FragmentManager:Fragment已从FragmentManager移除重要mAdded是因,生命周期状态是果这个问题的根本原因是动画的生命周期与Fragment View的生命周期不同步Fragment View销毁流程→←第一道防线→←Crash触发点动画回调执行时机动画回调可能在View销毁后继续执行访问时,已为null抛出。
2026-01-06 15:56:46
710
原创 解决Google 广告引起的OOM
AdView内存泄漏:广告加载失败时,AdView没有被正确释放累积效应:长时间运行后,未释放的AdView对象累积,导致OOM。
2025-12-02 17:51:36
848
原创 Firebase上ANR Process ProcessRecord failed to complete startup原因分析
handleBindApplication完成后,如何通知AMS创建好进程,然后创建Activity?ATMS从待启动列表取出Activity → 启动。通过Binder回调机制。
2025-11-20 11:57:50
958
原创 Android 主线程性能优化实战:从 90% 降至 13%
Android主线程性能优化案例:从94%降至13% 📌 优化成果 主线程占用:94.13% → 13.16% (↓86%) UI渲染耗时:10.8秒 → 1.38秒 (↓87%) 帧率:掉帧 → 稳定60fps 🔍 问题定位 性能分析工具:使用Android Profiler的Java/Kotlin Method Recording模式录制10秒 Top Down分析:发现doFrame()占主线程94% Bottom Up追踪:定位到3个频繁调用requestLayout()的视图 🛠 优化策略
2025-11-11 17:59:18
1162
2
原创 Flow 责任链模式图解
场景:按钮快速点击 5 次,触发网络请求不使用 throttleFirst:▼ ▼ ▼ ▼ ▼请求1 请求2 请求3 请求4 请求5(浪费了 4 个请求)使用 throttleFirst(1000ms):▼ ▼请求1 请求5(只发起 2 个请求,节省 3 个)flow { }构建器的block参数决定是否调用上游collect冷流:条件不满足时不调用 collect,上游不执行,节省资源热流:始终调用 collect,只在 emit 时判断,适合持续数据流责任链断开。
2025-10-31 14:59:46
476
原创 Context.startForegroundService() did not then call Service.startForeground() bug解析
Q1:何时返回?返回时机:在和都被调用后立即返回关键点:返回时和还未执行耗时:约 50-200ms(同步 Binder 调用)Q2: 为什么会报错 "did not then call Service.startForeground()"?原因:在 30 秒内未调用机制:AnrTimer 延时消息超时触发解决:在第一时间调用javaoneway interface IApplicationThread { // ← 整个接口 oneway// ... 所有方法都是异步。
2025-10-23 16:48:03
919
1
原创 ViewModel 配置变化保存机制深度解析
ViewModel 在配置变化(如屏幕旋转)时能够保持数据不丢失,这背后是一套复杂的 Framework 层和应用层协同工作的机制。本文将从系统检测到配置变化开始,逐步分析整个数据保存和恢复的过程。ActivityClientRecord 是关键载体在配置变化时不会被销毁字段保存所有非配置数据通过复用同一个 ActivityClientRecord 实现数据传递mChangingConfigurations 标志是判断依据在时设置为 true。
2025-10-21 10:42:46
500
原创 Fragment mWho 在registerForActivityResult 中作用
测试的时候会开启“不保活activity”,所以当从一个activity A中一个fragment,跳转到另一个activity B,然后setResult 返回activity A,activity A重建,fragment没有获取到结果。在oncreate 中加上 savedInstanceState == null 判断才能收到结果。
2025-10-16 14:49:03
606
原创 osmdroid 地图导航时,内存抖动
看到一直在调用setExpectedCenter(),定位到当接受到坐标时会把当前的坐标点设置为中心点,设置为中心点的时候,会按这个中心点生成一个bitmap 地图碎片,导航时,会不停的更新坐标,会不断的生成的bitmap,所以会有内存抖动。既然是由于不断的设置中心点出现的原因,那就减少设置中心点,只有当前位置跟中心点偏离60dp的时候才设置中心点。打开org.osmdroid.views.MapView 地图导航的时候明显的可以看出有内存抖动的现象,
2025-09-22 16:44:06
341
原创 ReportFragment:Android 生命周期的桥梁与兼容性解决方案
ReportFragment 是 Android 生命周期管理的重要组件,它通过巧妙的兼容性设计解决了不同 API 版本下的生命周期监听问题。然而,这种设计也带来了在 API 29 以下版本中的使用限制——当 FragmentManager 正在执行生命周期相关事务时(mExecutingActions = true),尝试执行 popBackStackImmediate() 或类似操作会抛出异常。立即执行命令:如和延迟执行命令:如commit()
2025-09-22 14:12:20
1069
1
原创 kotlin 协程取消机制
2这个地方是获取挂起函数结果的地方,会判断是不是异常导致fail的,如果是就抛出异常,然后invokesuspend 方法结束,后面的代码不再执行(异常抛出是在suspend返回结果的时候)总结:协程取消机制,使用了throw exception 机制,抛出异常后,代码执行跳转到catch执行,不再执行后面代码。异常抛出是在suspend返回结果的时候,所以不要在suspend 函数外面try catch,这样会把。3外面的try catch 捕捉异常,封装异常,把异常传给父协程,一样的道理。
2025-09-08 19:57:13
375
原创 openStreetMap SSL报错
或者openssl s_client -connect nominatim.openstreetmap.org:443 -verify_return_error。公司项目使用开源地图OpenStreetMap,在6.0手机出现CertPathValidatorException。有的手机上没有所以得下载下来放到,这种方法可以兼容到7.0。可以看出根证书是 ISRG Root X1 证书。通过上面的命令获取到证书链。
2025-08-07 17:19:37
190
原创 Android 公钥证书
公钥只跟keystore有关,class文件变化不影响公钥证书信息。获取的是公钥证书信息,而不是通过私钥对apk签名信息,
2025-08-06 10:55:10
144
原创 NestedScrollView嵌套RecyclerView 高度失效的原因
<androidx.core.widget.NestedScrollView android:layout_width="match_parent" android:layout_height="match_parent" > <LinearLayout android:layout_width="match_parent" android:layout_height="40.
2021-04-07 16:17:48
2422
原创 Android 组件化
1.什么是组件化组件化简单概括就是把一个功能完整的App或模块拆分成多个子模块, 每个子模块可以独立编译和运行, 也可以任意组合成另一个新的App或模块, 每个模块即不相互依赖但又可以相互交互。2.组件间通信组件:代码隔离,源码级别的的隔离,打包Apk会把代码,资源合并,形成一个app,运行在Android系统上共用一个用户空间。因为组件处于同一内存空间,所以可以通过反射直接调用,但是这种通信方式,随着组件的增多,组件之间的交互复杂多变,组件间耦合性强,所以使用中介者模式...
2021-02-28 09:06:38
328
原创 Glide 原理
当一个对象的状态变化时,通知另一个对象,很容易想到用到了观察者模式,那便有被观察者,观察者,用于管理观察者的管理类。以监听Activity的生命周期为例,被观察者是Activity,Request请求为观察者,下面分析源码1.在当前Activity的FragmentManager中加入RequestManagerFragment,Fragement的生命周期跟Activity的生命周期相关联...
2020-02-18 17:20:31
383
原创 解析Retrofit 原理
Retrofit 主要的实现原理是动态代理,它的实现步骤主要有:1.ServiceMethod解析接口方法上的注解,生成Okhttp.Request需要的参数,根据解析参数生成okhttp3.Call;2.生成OkHttpCall,作为okhttp3.Call的代理类;3.CallAdapter把OkHttpCalll转换为Observable;public <T> ...
2020-01-14 14:05:08
291
原创 Rxjava线程调度原理
Rxjava 有两个链:1.自下向上调用Observable的subscribe方法,2.自上向下调用Observer的onNext方法。自下向上到ObservableOnSubscribe的subscribe方法,然后开始自上向下。线程切换是用subscribeOn和observeOn两个方法,它们生成的Observable对象都有Scheduler,Scheduler就是用来帮它们实现线程...
2020-01-09 15:23:48
528
原创 Activity 启动方式singTask和singInstance的区别
在cmd 命令窗口运行 adb shell dumpsys activity activities,会打印出activity任务栈信息管理Activity从上到下display->stack->task->ActivityRecord。可以从cmd命令窗口总结出:以下情况 ,taskAffiny使用默认值,taskAffiny是用来指定activity的...
2019-09-17 16:39:32
1691
原创 webview 第二次调用loadUrl页面不刷新
一个需求,当点击Button按钮时,希望加载另一个Url。以下方法可以成功@Overridepublic void onClick(View view) { webview.loadUrl(url); webview.loadUrl( "javascript:window.location.reload( true )" );}亲测管用...
2019-09-05 15:06:49
5790
2
原创 Fragement 生命周期原理源码解析
一、概述 Activity作为Android四大组件,它的生命周期是由ActivityManager管理。Fragement生命周期根本上是由Activity管理,比如Activity被回调onCreate时,onCreate方法调用顺序:FragmentController->FragmentManager->Fragment,同步调用Fragment的onCre...
2019-09-02 14:47:33
266
原创 浅谈Rxjava原理
rxjava主要分为两个大类:Observable(被观察着)和Observer(观察者)运用责任链模式,有两个链条:Observable链条和Observer链条一.Observable链条生成过程Observable.create().map().map();1.Observable.create() 创建Observablecreate对象,2.调用map方法创建Obs...
2019-08-30 18:04:05
334
原创 dispatchTouchEvent源码分析
dispatchTouchEvent 方法可以根据DOWN事件和move,up事件分别分析。本文章不考虑多触摸点,TouchTarget链是储存了多触摸点,pointerIdBits 属性表示触摸点Id1.DOWN事件,主要作用是确定消费路线(把处理事件的View赋值给mFirstTouchTarget)具体过程:遍历子view ,判断触摸点是否在该view中,不在,跳过该viewi...
2019-06-03 15:48:41
330
原创 module.exports与exports的区别
每一个node.js文件都会创建一个module对象,同时,module对象会创建一个叫exports的属性,属性值为一个对象,初始值为{}。module.exports={ }。module.exports是每个nodejs文件对外输出的值,require请求到的值就是module.exports这个值。aa.js文件var hello=function () { console.info...
2018-04-17 14:55:14
292
原创 android handler源码理解
第一步,生成Looper和MessageQueue。如果在子线程中需要先执行Looper.prepare(),生成Looper对象,储存在ThreadLocal中(实际上是储存在线程的一个成员变量threadlocals中,主要作用是隔离变量),在Looper对象中生成MessageQueue对象。private static void prepare(boolean quitAllowe...
2018-04-05 23:12:21
224
原创 Android view的事件分发
从activity到viewgroup到view1.当onInterceptTouchEvent为false(不拦截)、onTouchEvent 为false 不消费以下为执行顺序,先执行dispatchTouchEvent 再执行onTouchEvent从Activity的dispatchTouchEvent -> n个viewgroup...
2018-04-03 13:46:48
253
原创 Java编译期和运行期
编译期: 是指把源码交给编译器编译成计算机可以执行的文件的过程.在Java中也就是把Java代码编成class文件的过程.编译期只是做了一些翻译功能,并没有把代码放在内存中运行起来,而只是把代码当成文本进行操作,比如检查错误.运行期:是把编译后的文件交给计算机执行.直到程序运行结束.所谓运行期就把在磁盘中的代码放到内存中执行起来.在Java中把磁盘中的代码放到内存中就是类加载过程.类加载是运行期的...
2018-03-17 23:09:31
7929
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅