自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 解决Google 广告引起的OOM

AdView内存泄漏:广告加载失败时,AdView没有被正确释放累积效应:长时间运行后,未释放的AdView对象累积,导致OOM。

2025-12-02 17:51:36 803

原创 Firebase上ANR Process ProcessRecord failed to complete startup原因分析

handleBindApplication完成后,如何通知AMS创建好进程,然后创建Activity?ATMS从待启动列表取出Activity → 启动。通过Binder回调机制。

2025-11-20 11:57:50 783

原创 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 1055 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 415

原创 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 861 1

原创 ViewModel 配置变化保存机制深度解析

ViewModel 在配置变化(如屏幕旋转)时能够保持数据不丢失,这背后是一套复杂的 Framework 层和应用层协同工作的机制。本文将从系统检测到配置变化开始,逐步分析整个数据保存和恢复的过程。ActivityClientRecord 是关键载体在配置变化时不会被销毁字段保存所有非配置数据通过复用同一个 ActivityClientRecord 实现数据传递mChangingConfigurations 标志是判断依据在时设置为 true。

2025-10-21 10:42:46 442

原创 Fragment mWho 在registerForActivityResult 中作用

测试的时候会开启“不保活activity”,所以当从一个activity A中一个fragment,跳转到另一个activity B,然后setResult 返回activity A,activity A重建,fragment没有获取到结果。在oncreate 中加上 savedInstanceState == null 判断才能收到结果。

2025-10-16 14:49:03 553

原创 osmdroid 地图导航时,内存抖动

看到一直在调用setExpectedCenter(),定位到当接受到坐标时会把当前的坐标点设置为中心点,设置为中心点的时候,会按这个中心点生成一个bitmap 地图碎片,导航时,会不停的更新坐标,会不断的生成的bitmap,所以会有内存抖动。既然是由于不断的设置中心点出现的原因,那就减少设置中心点,只有当前位置跟中心点偏离60dp的时候才设置中心点。打开org.osmdroid.views.MapView 地图导航的时候明显的可以看出有内存抖动的现象,

2025-09-22 16:44:06 277

原创 ReportFragment:Android 生命周期的桥梁与兼容性解决方案

ReportFragment 是 Android 生命周期管理的重要组件,它通过巧妙的兼容性设计解决了不同 API 版本下的生命周期监听问题。然而,这种设计也带来了在 API 29 以下版本中的使用限制——当 FragmentManager 正在执行生命周期相关事务时(mExecutingActions = true),尝试执行 popBackStackImmediate() 或类似操作会抛出异常。立即执行命令:如和延迟执行命令:如commit()

2025-09-22 14:12:20 984 1

原创 kotlin 协程取消机制

2这个地方是获取挂起函数结果的地方,会判断是不是异常导致fail的,如果是就抛出异常,然后invokesuspend 方法结束,后面的代码不再执行(异常抛出是在suspend返回结果的时候)总结:协程取消机制,使用了throw exception 机制,抛出异常后,代码执行跳转到catch执行,不再执行后面代码。异常抛出是在suspend返回结果的时候,所以不要在suspend 函数外面try catch,这样会把。3外面的try catch 捕捉异常,封装异常,把异常传给父协程,一样的道理。

2025-09-08 19:57:13 307

原创 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 157

原创 Android 公钥证书

公钥只跟keystore有关,class文件变化不影响公钥证书信息。获取的是公钥证书信息,而不是通过私钥对apk签名信息,

2025-08-06 10:55:10 101

原创 Android 跳转外部浏览器坑

Android 跳转外部浏览器坑

2022-11-04 18:03:42 1896

原创 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 2373

原创 Android 组件化

1.什么是组件化组件化简单概括就是把一个功能完整的App或模块拆分成多个子模块, 每个子模块可以独立编译和运行, 也可以任意组合成另一个新的App或模块, 每个模块即不相互依赖但又可以相互交互。2.组件间通信组件:代码隔离,源码级别的的隔离,打包Apk会把代码,资源合并,形成一个app,运行在Android系统上共用一个用户空间。因为组件处于同一内存空间,所以可以通过反射直接调用,但是这种通信方式,随着组件的增多,组件之间的交互复杂多变,组件间耦合性强,所以使用中介者模式...

2021-02-28 09:06:38 295

原创 Glide 原理

当一个对象的状态变化时,通知另一个对象,很容易想到用到了观察者模式,那便有被观察者,观察者,用于管理观察者的管理类。以监听Activity的生命周期为例,被观察者是Activity,Request请求为观察者,下面分析源码1.在当前Activity的FragmentManager中加入RequestManagerFragment,Fragement的生命周期跟Activity的生命周期相关联...

2020-02-18 17:20:31 361

原创 解析Retrofit 原理

Retrofit 主要的实现原理是动态代理,它的实现步骤主要有:1.ServiceMethod解析接口方法上的注解,生成Okhttp.Request需要的参数,根据解析参数生成okhttp3.Call;2.生成OkHttpCall,作为okhttp3.Call的代理类;3.CallAdapter把OkHttpCalll转换为Observable;public <T> ...

2020-01-14 14:05:08 262

原创 Rxjava线程调度原理

Rxjava 有两个链:1.自下向上调用Observable的subscribe方法,2.自上向下调用Observer的onNext方法。自下向上到ObservableOnSubscribe的subscribe方法,然后开始自上向下。线程切换是用subscribeOn和observeOn两个方法,它们生成的Observable对象都有Scheduler,Scheduler就是用来帮它们实现线程...

2020-01-09 15:23:48 496

原创 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 1645

原创 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 5744 2

原创 Fragement 生命周期原理源码解析

一、概述 Activity作为Android四大组件,它的生命周期是由ActivityManager管理。Fragement生命周期根本上是由Activity管理,比如Activity被回调onCreate时,onCreate方法调用顺序:FragmentController->FragmentManager->Fragment,同步调用Fragment的onCre...

2019-09-02 14:47:33 249

原创 浅谈Rxjava原理

rxjava主要分为两个大类:Observable(被观察着)和Observer(观察者)运用责任链模式,有两个链条:Observable链条和Observer链条一.Observable链条生成过程Observable.create().map().map();1.Observable.create() 创建Observablecreate对象,2.调用map方法创建Obs...

2019-08-30 18:04:05 299

原创 dispatchTouchEvent源码分析

dispatchTouchEvent 方法可以根据DOWN事件和move,up事件分别分析。本文章不考虑多触摸点,TouchTarget链是储存了多触摸点,pointerIdBits 属性表示触摸点Id1.DOWN事件,主要作用是确定消费路线(把处理事件的View赋值给mFirstTouchTarget)具体过程:遍历子view ,判断触摸点是否在该view中,不在,跳过该viewi...

2019-06-03 15:48:41 299

原创 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 259

原创 android handler源码理解

第一步,生成Looper和MessageQueue。如果在子线程中需要先执行Looper.prepare(),生成Looper对象,储存在ThreadLocal中(实际上是储存在线程的一个成员变量threadlocals中,主要作用是隔离变量),在Looper对象中生成MessageQueue对象。private static void prepare(boolean quitAllowe...

2018-04-05 23:12:21 200

原创 Android view的事件分发

从activity到viewgroup到view1.当onInterceptTouchEvent为false(不拦截)、onTouchEvent 为false 不消费以下为执行顺序,先执行dispatchTouchEvent 再执行onTouchEvent从Activity的dispatchTouchEvent -> n个viewgroup...

2018-04-03 13:46:48 237

原创 Java编译期和运行期

编译期: 是指把源码交给编译器编译成计算机可以执行的文件的过程.在Java中也就是把Java代码编成class文件的过程.编译期只是做了一些翻译功能,并没有把代码放在内存中运行起来,而只是把代码当成文本进行操作,比如检查错误.运行期:是把编译后的文件交给计算机执行.直到程序运行结束.所谓运行期就把在磁盘中的代码放到内存中执行起来.在Java中把磁盘中的代码放到内存中就是类加载过程.类加载是运行期的...

2018-03-17 23:09:31 7881

空空如也

空空如也

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

TA关注的人

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