- 博客(2204)
- 资源 (15)
- 收藏
- 关注
原创 我写的《高性能Android开发技术》一书已正式出版全国发行
我写的《高性能Android开发技术》一书,已由北京航空航天大学出版社正式出版并全国发行,京东上的发售页面链接地址:https://item.jd.com/12602702.html感谢北京航空航天大学出版社,感谢北京航空航天大学出版社的董宜斌先生、张冀青老师,感谢优快云,感谢给予我帮助和支持的人!谢谢你们!我的邮箱:zhangphil@live.com...
2019-05-11 23:10:56
4578
13
原创 海量小文件造成Android存储碎片化与I/O变慢
几百万个小文件(如每文件仅几十字节)虽不必然导致传统数据碎片,但引发显著的存储浪费与性能瓶颈:每个文件占用至少4KB块空间及独立元数据,造成大量块浪费与元数据膨胀;频繁访问触发海量随机元数据读取、路径解析与系统调用,拖慢I/O,尤其在目录遍历、扫描、清理等操作中表现明显;对F2FS文件系统更加剧GC压力、写放大与延迟抖动。平铺百万级文件于单一目录亦加剧管理开销。根本问题非“内容小”,而是“访问成本高”。
2026-11-02 23:44:37
120
原创 Agent决定做什么,Skill定义怎么做,MCP让它能调用外部能力
在MCP架构中,Agent负责任务决策,Skill定义执行流程,MCP提供外部工具调用能力。以“Hello,World!”为例:Agent识别需求后调用hello-world Skill,该Skill通过MCP调用say_hello工具,返回结果。三者协同实现能力复用与解耦。虽非强制组合,但典型企业场景中,Agent通过Skill编排MCP工具,连接GitLab、Jira等系统,实现自动化工作流。
2026-10-29 23:23:44
175
原创 Google ADK最简Hello,World Skill:Python函数注册为Agent可调用的 Tool
本文以Google ADK(Python)为例,演示如何将一个Python函数注册为Agent可调用的Tool,实现最简“Hello, World”技能。核心在于通过tools=[hello_world]将函数注入Agent,由模型根据用户意图自主调用。该模式可扩展至真实业务能力(如查询Jira、读取飞书文档),强调输入输出规范、职责单一与可观测性,是构建可复用、可测试研发智能Agent的基础路径。
2026-10-28 23:15:42
258
原创 AI Agent、Skills、Google ADK三者关系
AIAgent是任务决策与编排核心,Skills是具体能力(如查Jira、写代码),GoogleADK则是构建Agent的开发框架。ADK提供通用底座(如调度、日志、部署),但不自带企业业务能力。通用任务可复用内置工具(如搜索、文件处理);而内部系统接入、SOP流程、高风险操作仍需定制Skills(以FunctionTool、MCP、Sub-Agent等形式实现)。关键:ADK不是万能代理,而是高效搭建Agent与Skills组合的框架——“能用”不等于“自动会”,业务能力仍需主动配置。
2026-10-27 23:05:40
403
原创 Android doFrame出1帧耗时远超1个VSYNC信号,屏显会发生什么?
在90Hz屏幕下,若Android应用doFrame耗时70ms(远超11.11ms刷新周期),将错过约6个VSync信号。屏幕会持续显示旧帧(如F0),用户感知为“卡顿一下,画面突然跳变”。错过的帧不会补播,后续帧按当前时间对齐新VSync,不会整体延迟70ms。最终帧可能迟到上屏,甚至被后续新帧覆盖,导致视觉“跳帧”。若持续超时或BufferQueue堆积,才会引发连续掉帧与输入延迟。关键在于:卡顿≠每帧都延迟,而是局部失序与丢帧。
2026-10-22 23:12:27
376
原创 Android相机拍完照跳转进大图链路拆解
本文拆解了Android相机拍完照跳转至大图的跨进程、跨系统链路,通过Perfetto+Trace精准定位14个关键时间点,将耗时细分为相机侧、系统启动、图库冷启动、页面初始化、首图加载及首帧绘制六大阶段。重点分析各环节瓶颈:相机是否等待MediaStore就绪、图库Application初始化同步阻塞、Activity布局过重、首图加载策略是否合理,以及RenderThread与SurfaceFlinger的渲染延迟。强调需结合多层打点与录屏帧确认真实用户感知首帧时间,优化关键路径以提升体验。
2026-09-10 23:02:24
255
原创 AI大模型生成maxTokens 与上下文context
但端侧小模型要注意耗时和发热。maxTokens表示模型本次最多输出多少 token。它决定回答长度上限,也直接影响生成耗时、耗电、发热和上下文占用。值越大,回答可能越长,但端侧生成越慢;值越小,响应更快,但回答可能不完整。
2026-09-04 23:25:51
372
原创 Android main thread主线程Choreographer doFrame发生FullSuspendCheck
<think>我们根据要求,生成≤150字的文章摘要。需要涵盖关键点:FullSuspendCheck是什么(ART的线程安全点响应挂起请求),在doFrame中出现表示主线程在该帧执行期间响应ART挂起请求;常见触发原因包括GC相关线程暂停、线程管理、调试采样等;结论是排查时优先确认同期是否有GC/SuspendAll等活动。但必须控制在150字内(中文字数?)。应精简。 先整理要点:FullSuspendCheck是主线程在安全点响应ART挂起请求,出现在doFrame中不代表代码直接调用,
2026-09-03 00:34:10
285
原创 Windows Server+Caddy+FastAPI+llama.cpp+Qwen实现AI聊天机器人技术架构(2)
本文介绍了从个人自用升级为公共服务架构的AI聊天机器人技术方案。架构采用分层设计:前端Android App通过HTTPS访问API网关(Caddy/Nginx),后端由无状态FastAPI服务、推理调度层和Worker池(llama.cpp/vLLM)组成,支持水平扩展。关键改进包括:1) 从单用户限制改为可配置的并发控制;2) 采用流式响应和有限队列保护系统;3) 抽象推理层接口便于后续切换GPU方案;4) 增加监控告警体系。初期可在4GB内存Windows服务器部署llama.cpp运行Qwen小模型
2026-09-02 00:35:36
413
原创 Android端本地文本聊天大模型GGUF文件500MB~800MB选项
这是这个 500~800MB 区间里,最值得优先尝试的类型。如果你的 Android 设备内存很紧,可以用它作为兜底。在这个体积段里,通常比 0.5B 高精度量化更聪明。可能略低于 500MB,效果不如 1.5B 低量化。模型,它可以落在 500~800MB 以内。效果更好,但通常超过你的 800MB 限制。体积合适,但量化损失较明显。量化精度高,但模型本身太小。,通常会超过 800MB。,聊天效果通常更好。
2026-09-01 00:41:52
285
原创 Android性能分析优先级反转Priority Inversion
主线程 / UI Thread优先级高,应该优先获得 CPU主线程↓发起后台低优任务↓主线程同步等待结果↓后台任务因为优先级低抢不到 CPU↓后台任务迟迟不返回↓主线程一直阻塞↓前台应用卡顿 / 掉帧 / ANR高优先级的主线程,被一个低优先级后台任务反向卡住。这就是典型的。
2026-08-31 00:26:45
226
原创 Android 两层强弱内存缓存:StrongMemoryCache与WeakMemoryCache
这两个开关并不是“两种互斥缓存策略”,而是共同组成一个。
2026-08-29 00:11:00
393
原创 AI大模型生成文本采样参数temperature
控制模型输出的随机性:值越低,回答越稳定、保守;值越高,回答越多样、发散、有创意,但也更容易胡说和跑题。再根据实际效果微调。
2026-08-28 01:23:11
328
原创 llama.cpp用Android NDK编译成so动态库,Kotlin通过JNI调用
本文详细介绍了在Android应用中通过Kotlin调用llama.cpp模型的完整方案。主要内容包括: 两种实现方案对比:推荐使用Android Studio+CMake+NDK的集成方案,优于单独编译.so的方式。 技术架构:Kotlin负责UI层,通过JNI调用C++封装的llama.cpp接口,模型文件存储在本地。 关键实现步骤: NDK和CMake环境配置 llama.cpp作为子模块集成 CMakeLists.txt配置优化 JNI接口设计(初始化、推理、释放等) Kotlin与C++的数据交互
2026-08-27 00:20:27
548
原创 Android Record View draw,View DisplayList/RenderNode标记为dirty,重新录制 View#draw 绘制命令
而出现在下面,说明它们是在某个 View 的绘制链路里被同步执行了。
2026-08-26 00:14:41
219
原创 Android端侧AI / On-device LLM / 重客户端本地大模型推理架构
本文提出了一种适用于Android设备的本地化大语言模型推理架构方案,核心是将模型文件控制在300MB以内,实现端侧AI聊天功能。主要推荐使用Qwen2.5-0.5B-Instruct模型的量化版本(Q3_K_S/Q3_K_M约250-300MB),并设计了包含模型管理、设备检测、本地推理等7层架构。方案采用App首次启动后下载模型的模式,通过轻量后端实现模型分发和统计,不依赖服务器推理。针对不同设备性能提供两档模型选择,并详细说明了内存占用、隐私保护等技术细节,为移动端本地化AI应用提供了可行的实施方案。
2026-08-25 00:35:53
523
原创 Windows Server+Caddy+FastAPI+llama.cpp+Qwen实现AI聊天机器人技术架构(1)
本文提出了一种基于低配Windows VPS(4GB内存/2核CPU)的AI聊天机器人技术架构方案。该架构采用Android App作为客户端,通过HTTPS REST API访问远程服务,服务端由Caddy反向代理、FastAPI业务层和llama.cpp模型推理层组成,加载Qwen2.5小量化模型(推荐0.5B Q4_K_M版本)。设计重点包括:1)严格资源控制(输入限制800字/输出256token);2)无上下文处理降低内存压力;3)流式响应改善用户体验;4)单并发避免过载;5)极简架构(无数据库/
2026-08-24 00:04:30
281
原创 Python Web后端框架FastAPI vs Flask
摘要: FastAPI与Flask是两大Python Web框架,适用场景不同。Flask轻量灵活,适合简单项目、传统Web应用及快速开发;FastAPI基于类型注解,支持异步、自动校验及文档生成,性能更优,适合REST API、AI服务接口及中大型项目。核心差异: 开发体验:Flask自由直接,FastAPI规范严谨; 性能:FastAPI异步优势明显,高并发场景更佳; 生态:Flask插件丰富,FastAPI更适合现代API开发; 部署:Flask常用Gunicorn,FastAPI推荐Uvicorn。
2026-08-23 00:05:59
758
原创 Caddy:Go语言的现代https Web服务器
Caddy是一款用Go语言开发的现代化Web服务器,以自动HTTPS功能著称。它能自动申请和续期SSL证书,简化HTTPS配置流程。作为反向代理工具,Caddy可将外部请求安全转发到本地服务(如FastAPI),同时提供访问控制、压缩、流式传输支持等功能。相比Nginx,Caddy配置更简洁,特别适合个人项目和小型服务部署。在聊天机器人架构中,Caddy充当安全网关,处理HTTPS加密、域名访问和请求转发,保护后端服务不被直接暴露。其单文件部署、跨平台支持等特性使其成为轻量级Web服务的理想选择。
2026-08-22 16:37:13
301
原创 Android Studio中把llama.cpp编译Android .so
本文介绍了一个在Android Studio中集成llama.cpp的最小Demo实现方案,通过JNI将llama.cpp编译为Android.so库,实现本地加载GGUF模型进行文本生成。文章详细说明了项目结构配置(SDK≥30,NDK≥28)、CMake编译设置、Kotlin-JNI-C++的完整调用链实现,以及模型文件部署方式。该Demo采用每次请求新建上下文的简化设计,包含加载模型、生成文本、资源释放等核心功能,并提供了错误排查建议。项目舍弃了上下文保持等复杂功能以确保稳定性,适合作为端侧大语言模型
2026-08-20 23:09:10
513
原创 Android Framework/BootClassPath系统Java库文件core-icu4j.jar
摘要: core-icu4j.jar是Android系统Java库,提供国际化支持(如日期、语言、字符集处理)。在Android 10+中,路径通常为/apex/com.android.i18n/javalib/core-icu4j.jar,Android 9及更早版本为/system/framework/core-icu4j.jar。文件大小约为10MB~15MB,具体值需通过adb shell命令(如ls -lh或stat)在目标设备上确认。示例命令: adb shell 'ls -lh /apex/c
2026-08-18 23:24:39
359
1
原创 Unity3D(Unity)跨平台游戏引擎简介
Unity3D是一款功能强大的跨平台游戏引擎,由Unity Technologies开发。它整合了渲染引擎、物理系统、动画工具等核心组件,支持2D/3D游戏开发及VR/AR等实时交互应用。主要特点包括:可视化编辑器、C#脚本编程、丰富的资源商店和强大的跨平台发布能力(支持移动端/主机/PC等20+平台)。Unity显著降低了开发门槛,特别适合中小团队,在移动游戏和独立游戏领域应用广泛。虽然存在包体优化等挑战,但其高效的工作流程和完整的生态体系使其成为游戏开发的主流选择之一。
2026-08-15 23:06:45
605
原创 Plants vs. Zombies / PvZ,Android
《植物大战僵尸》官方游戏受版权保护,GitHub上常见的开源Android项目主要分为引擎移植和玩法仿制两类。推荐两个较优质的开源项目:1)PvZ-Portable(跨平台重构),支持多系统并追求原版体验,需自行提供合法资源;2)PlantsVsZombies-AndroidTV(TV适配版),专注大屏设备优化。二者均不包含原版素材,仅代码开源,适合学习研究而非商业用途。普通手机用户推荐关注第一个项目,但需注意资源合法性。
2026-08-14 23:02:09
588
原创 Android BitmapFactory实现AOSP ContentResolver.loadThumbnail快速取小缩略图,Kotlin
本文深入分析了Android中快速加载缩略图的实现原理。关键点在于:1)通过openTypedAssetFileDescriptor传入目标尺寸,让MediaProvider直接返回合适的缩略图,避免全尺寸解码;2)采用二次采样策略,先获取图片尺寸计算采样率,再按需解码;3)处理方向信息时优先使用Provider提供的元数据;4)最终仍做防御性缩放确保尺寸合规。文中提供了基于BitmapFactory的Kotlin实现方案,吸收系统优化思路的同时,也指出其与系统实现(如ImageDecoder)的性能差异,
2026-08-13 23:11:23
429
原创 Android Coil 3 ImageRequest.Builder error() 和 fallback()异同
在Coil3的ImageRequest.Builder中,error()和fallback()都用于配置加载失败时的兜底图,但触发条件不同。error()在data非空但加载失败(如网络错误、文件不存在等)时触发;fallback()则在data为空时使用。两者通常与placeholder()配合使用:placeholder()显示加载中,fallback()处理无数据情况,error()处理加载失败。建议同时配置两者以明确区分"无数据"和"加载失败"场景,使语义更清
2026-08-11 23:01:53
386
原创 Android简单BitmapPool实现,Kotlin
本文介绍了Android中使用Kotlin实现简单BitmapPool的核心要点。主要内容包括:1)创建SimpleBitmapPool对象管理可复用Bitmap,通过inMutable和inBitmap参数实现复用;2)实现固定尺寸(最大200x200)的RGB_565格式图片解码方法decodeFileWithPool200;3)提供inSampleSize计算逻辑使解码结果接近目标尺寸;4)示例在RecyclerView中使用该BitmapPool,在视图回收时将Bitmap放回池中。该方案能有效减少
2026-08-10 23:26:25
231
原创 Android应用虚拟化/App Virtualization/沙箱多开/应用分身/双开/多开
Android 里通常叫。尤其是微信这类复杂 App,涉及推送、相机、文件、WebView、账号风控、签名校验、后台保活等,普通开源框架往往只能做到“部分可用”。
2026-08-08 23:14:06
676
原创 Kotlin对象的深/浅copy
Kotlin实现对象复制主要有以下几种方式: 推荐使用data class的copy()方法实现浅拷贝,也可通过copy(field=newVal)修改部分字段 对于深拷贝,需要手动复制嵌套对象,如user.copy(address=address.copy()) 非data class可自定义copy()或deepCopy()方法 不推荐使用Java的Cloneable接口 复杂对象可使用序列化实现深拷贝,但性能较差 集合类型需要注意容器和元素的深拷贝问题 最佳实践是优先使用data class的copy
2026-08-07 23:03:36
255
原创 Android基于LinkedHashMap实现LRU缓存原理和方法
本文介绍了Android中基于LinkedHashMap实现LRU缓存的原理和实现方法。关键点在于LinkedHashMap的accessOrder参数设为true,使得元素按访问顺序而非插入顺序排列,最近访问的会被移到队尾,超出容量时优先淘汰队首元素。文章提供了Kotlin和Java两种版本的Bitmap缓存实现,详细说明了容量控制、淘汰机制和注意事项,特别强调了谨慎处理Bitmap回收以避免显示异常。相比自定义实现,推荐优先使用Android官方提供的LruCache类,但在高版本系统中需要注意内存计算
2026-08-06 23:25:51
259
原创 PSS/RSS废弃了?Android/Google主推memory cgroup(memcg)衡量和管理App内存?
摘要: Android系统正逐渐转向使用memory cgroup(memcg)作为应用内存管理的主要机制,而非传统的PSS/RSS指标。PSS/RSS仍用于调试(如dumpsys meminfo),但存在共享内存重复计算(RSS)、统计成本高(PSS)等问题,且无法准确反映系统内存回收收益。memcg通过内核级资源隔离和聚合统计(按UID/进程组),更贴近LMKD/OOM等系统管理逻辑,支持实时低开销监控。查看memcg数据需区分cgroup v1(/dev/memcg)或v2(/sys/fs/cgrou
2026-08-05 23:10:43
300
原创 Android Coil 3为什么没有沿用Glide那种BitmapPool体系?是偷懒、退化,还是一次正确的架构取舍?
Coil3放弃Glide式BitmapPool是适应现代Android环境的合理选择。随着Android系统优化(ART改进、硬件Bitmap普及)和设备内存提升,频繁分配Bitmap的性能损耗显著降低,而维护BitmapPool带来的架构复杂性和潜在风险(内存占用、图片错乱)日益凸显。Coil3优先采用不可变图片和硬件加速方案,简化资源管理,在大多数场景下更高效稳定。仅对特定高频软件解码场景(如图库快速滑动),BitmapPool仍可能有局部优势,但此时应优先优化缓存策略而非引入复杂池化机制。这一取舍体现
2026-08-04 23:03:27
272
原创 Android Activity调用finish()后,所有View是如何走向毁灭的?
本文详细解析了Android Activity调用finish()后View的销毁过程。关键点包括:1) finish()触发Activity生命周期进入onDestroy;2) WindowManager移除DecorView;3) ViewRootImpl断开连接并递归触发各View的onDetachedFromWindow;4) Java对象需等待GC回收,native资源由系统异步释放;5) RecyclerView、Bitmap等组件会执行特定清理;6) 开发者应在适当时机(如onDestroy)
2026-08-03 23:01:35
405
原创 Android JPEG/PNG解码过程在Linux内核page cache中占用的数据页规模
Android系统解码JPEG/PNG图片时,文件数据在Linux内核pagecache中的占用规模主要取决于文件大小和系统页大小。对于5MB的本地图片文件,若被完整读取,pagecache占用通常约为5MB(按4KB页大小向上取整为5,001,216字节)。实际占用可能因多种因素变化:是否完整读取文件、系统内存回收机制、文件访问方式(read/mmap)、是否只读取元数据等。关键点包括:pagecache以页为单位管理(4KB/16KB),多进程共享同一文件的缓存,且需注意解码后的Bitmap内存(如40
2026-08-02 15:03:21
369
原创 Android ContentProvider/ContentResolver读图片,跨进程 IPC慢
Android系统通过ContentProvider读取图片涉及跨进程IPC调用,主要包括查询媒体库、打开文件描述符等步骤。对于本地MediaStore图片,实际文件读取通常通过获取的文件描述符直接访问,而非逐字节IPC传输。但在设备长时间运行的高负载环境下,可能出现MediaProvider进程繁忙、Binder堵塞、存储性能下降等问题,导致图片读取速度变慢甚至失败。不同来源的Uri(如MediaStore、DocumentsProvider、云服务)性能表现差异较大,云存储类Uri读取速度更易受影响。建
2026-08-01 19:54:28
499
原创 BLASTBufferQueue acquireNextBufferLocked: Can‘t acquire next buffer. Already acquired max frames
摘要:日志显示XxxActivity的BLASTBufferQueue因消费者侧(SurfaceFlinger/HWC)未及时释放缓冲,导致已占用6个缓冲(上限4+2),无法继续获取新缓冲,引发BufferQueue背压。此问题常出现在滑动场景中,原因包括App生产帧过快(如RecyclerView高频刷新)或系统消费过慢(合成/GPU延迟)。表现为滑动卡顿、dequeueBuffer阻塞,需通过Perfetto抓取图形链路数据(RenderThread/SurfaceFlinger)进一步定位生产或消费瓶
2026-07-31 23:36:33
383
原创 Android ImageDecoder/BitmapFactoryJPEG/PNG图片,内核读取原始图片文件产生大量 page cache
在Android应用中解码JPEG/PNG图片时,除了最终生成的Bitmap会占用内存外,内核还会因读取原始文件产生大量pagecache。这些pagecache虽不属于应用堆内存,但会与系统内存竞争资源,可能导致内存回收、IO抖动甚至应用卡顿和LMK杀进程。优化建议包括:始终按目标尺寸解码、优先使用FileDescriptor、建立缩略图磁盘缓存、控制后台解码并发、避免一次性加载大文件等。关键是通过减少原图读取、优化缓存策略来降低系统级内存压力,而非直接操作pagecache。性能分析时可结合meminf
2026-07-30 23:02:57
386
原创 Android OAID是什么?有什么功用?
OAID是国内安卓生态推出的匿名设备标识方案,用于替代IMEI等隐私敏感标识。它在保障用户隐私可控的前提下,为广告归因、用户分析、金融风控等场景提供稳定的设备识别能力。OAID具有稳定性高(覆盖率超95%)、用户可重置、无需高危权限等特点,已成为国内合规设备标识的主流选择。开发者可通过轻量级开源库快速接入,满足业务需求的同时确保合规性。该方案平衡了隐私保护与商业需求,是《个人信息保护法》实施后的重要技术解决方案。
2026-07-25 23:41:52
507
原创 MongoDB创建数据库时的Collection Name
MongoDB创建数据库时填写的CollectionName是该库首个集合的名称,相当于关系型数据库的表。命名规则包括:必须以字母或下划线开头,禁止使用$、空字符等特殊符号,命名空间总长度限制在255字节内。其核心作用是标识数据分组(如users、orders)、关联数据存储并简化操作。虽然MongoDB支持插入文档时自动创建集合,但预先指定CollectionName能更规范地初始化业务集合。注意避免使用system.前缀等保留字,且名称大小写敏感。
2026-07-23 23:05:58
247
原创 MongoDB 8.x从连接器mongo迁移到mongosh(MongoDB Shell)
MongoDB 8.x在Windows环境下已不再提供传统的mongo.exe,推荐使用新版mongosh(MongoDB Shell)。用户可通过官方下载中心获取Windows版mongosh安装包,解压后直接运行mongosh.exe。安装后可通过命令行验证版本并连接数据库(本地或远程)。此外,还推荐使用图形化工具如MongoDB Compass或第三方管理工具作为替代方案。这一变化从MongoDB 6.0开始实施,旨在推广功能更强大的新版Shell工具。
2026-07-22 23:25:11
396
MaterialDesignLibrary_Code and Lib合集
2015-09-21
链家2020年9月二手房数据
2020-12-10
strava_com_sample_utf8.xls
2020-12-10
digital-7字体(LED数字样式字体)
2017-09-05
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅