IT技术博客大学习 共学习 共进步

Android开发

共 55 篇文章

IT 2021-05-26 22:50:44 / 累计浏览 2,274

编译 RenderDoc 的安卓 apk(带interceptor-lib)

作者以亲身经历开篇:之前编译过安卓版的RenderDoc,但因未留笔记,再次需要时只能重头再来。这次他想为需要强Hook能力的版本做详细记录,因为核心的interceptor-lib组件依赖一个非常古老的LLVM版本,编译过程颇为繁琐。 文章的核心价值在于点出了一个官方文档中未明说的关键陷阱。尽管流程大体可循——先按指南配置好JDK/SDK/NDK,再克隆interceptor-lib并修改其构建脚本——但在实际使用CMake生成工程时,新版本CMake与Android NDK工具链的交互方式已经变化。直接使用常见的`-DANDROID_TOOLCHAIN=clang`参数实际上无效,导致构建会默认选用无法工作的GCC工具链。 作者给出的解决方法是使用正确的CMake参数:`-DCMAKE_ANDROID_NDK_TOOLCHAIN_VERSION=clang`,并指明了可参考的具体CMake模块文件路径。这个细微的修正,正是避免编译功亏一篑的关键。文章最终明确,遵循此调整后的步骤,即可成功编译出具备强Hook能力的RenderDoc安卓APK。

IT 2020-02-11 10:07:27 / 累计浏览 2,093

关于 Android 系统流畅性的一些思考

这篇讲的是 Android 流畅性问题的多维度分析。作者认为,用户常遇到的“卡顿”并非单纯是系统优化不足,而是硬件、系统、应用三者复杂交互的结果,需要跳出“甩锅系统”的简单思维。 文章从硬件层面展开,详细对比了 CPU 性能、GPU 强弱、内存大小、存储规格(UFS/eMMC)乃至屏幕分辨率和电池容量对流畅体验的直接影响。例如,内存不足会导致系统频繁杀后台与数据交换,造成操作迟滞;而盲目使用 2K 屏也可能在性能不足时拖累流畅度。 系统层面,作者深入剖析了国内厂商对应用管控、内存策略和进程调度的“魔改”逻辑,指出这主要是为了应对国内应用生态的混乱。同时,文章也提到了渲染线程、TripleBuffer 等底层机制如何共同作用,决定了一帧画面能否在 16 毫秒内完成渲染。 整体而言,作者试图为读者建立一个更全面的分析框架:下次遇到手机卡顿时,除了抱怨系统,或许可以想想是某个后台应用在作祟,或是硬件本身已力不从心。这种多角度的审视,有助于更理性地定位问题根源。

IT 2020-02-07 14:25:16 / 累计浏览 2,191

Android 性能优化必知必会

这篇讲的是Android性能优化的全面知识体系与资源导航。作者基于多年一线经验,坦言性能优化牵涉面广、挑战巨大,因此将自己积累的大量优质技术文章和文档汇总成文,旨在帮助新人快速入门,也作为个人知识的梳理与更新。 文章内容扎实,从“优化心得和经验”到“响应速度”等多个维度,系统性地整理了开发者必知的知识点。其中不仅包含Google官方的性能模式课程与开发指南,更汇集了美团、手机淘宝、微信、支付宝等一线大厂的实战复盘,如手淘全链路性能优化、微信内存优化、支付宝启动优化中的垃圾回收处理等深度实践。 此外,文章还提供了诸如Matrix TraceCanary卡顿监控、I/O质量检测、以及基于二进制文件重排的启动优化等具体技术方案的入口。整个资源库持续更新,为从事系统开发与优化的工程师提供了一份清晰的学习地图和问题解决参考。

IT 2020-02-01 15:18:13 / 累计浏览 2,495

Android 中低内存对性能的影响

这篇文章从实际性能问题出发,系统分析了 Android 系统在低内存状态下对整机性能的拖累。作者首先点明了问题背景:随着系统与应用膨胀,4GB 以下设备在日常使用中极易陷入低内存状态,并直观表现为应用启动慢、列表滑动掉帧、设备发热等现象。 文章详细拆解了低内存的数据与行为特征。开发者可以通过 `dumpsys meminfo` 观察到 Free RAM 极低、ZRAM 使用率飙升等关键指标,同时在系统日志中能看到 Low Memory Killer (LMK) 与 kswapd 线程异常活跃,频繁执行内存回收与进程查杀。 更深入的是,作者剖析了低内存导致卡顿的具体机制:内存不足引发磁盘 IO 频繁,会阻塞主线程;内核回收线程 kswapd 会抢占 CPU 资源,与前台应用竞争;而 LMK 激进查杀后台进程,又会触发应用重启,形成 CPU、内存与 IO 资源的恶性循环。文章还涵盖了相关的调试方法与潜在的优化方向。

IT 2019-03-28 22:20:17 / 累计浏览 1,710

react-native-navigation 简单分析和跨页跳转

这篇讲的是作者在实际项目中使用React Native官方推荐的导航库react-native-navigation时,所遭遇的一系列痛点及其深度解析。文章并非泛泛而谈,而是直指该库的核心设计——一套独立于RN生命周期的事件机制与页面堆栈模型,并剖析了由此引发的问题。 作者重点分析了其“push不销毁当前页”的机制,这虽可能出于性能考虑,却为独占系统资源(如相机、麦克风)的组件埋下了隐患。由于资源不会在路由切换时自动释放,可能引发后续页面无法正常初始化资源的严重问题。文章对此提出了利用Modal Stack或调整交互顺序的解决思路。 更具实践价值的是,文章还探讨了如何“绕过”该库的串行栈限制,实现产品要求的跨页跳转。作者提供了两种具体的技术方案:一种是利用`willAppear`和`didDisappear`生命周期配合状态控制,实现“跳过”中间页的视觉假象;另一种则是通过`props`回调在父子页面间传递指令,巧妙地实现了“接力pop”,从而达到跨页返回的目的。这些技巧展现了在框架限制下寻找灵活解决方案的工程智慧。

IT 2016-05-05 22:56:44 / 累计浏览 3,576

Maven依赖机制简介

这篇讲的是Maven作为构建工具,其核心且强大的依赖管理机制。作者从依赖如何被自动传递和解析讲起,详细拆解了传递性依赖背后的关键规则:当出现版本冲突时,Maven遵循“短路径优先”,在路径长度一致时则看POM声明顺序(第一声明原则)。 文章清晰地对比了六种不同的依赖范围(如compile、provided、runtime等),用表格明确了它们在编译、测试、运行时对classpath的影响以及如何相互传递,这是实际开发中配置依赖必须厘清的差异。 此外,文中还介绍了通过在父POM中集中管理依赖版本与排除项的方法,这对于维护大型多模块项目、保持依赖一致性非常实用。整体而言,文章从基础概念到复杂场景,系统梳理了Maven处理依赖的逻辑,能帮助开发者更好地掌控项目构建。

IT 2016-05-05 13:08:17 / 累计浏览 2,433

Android应用内存泄露分析、改善经验总结

这篇讲的是作者如何系统性地分析和改善Android应用的内存泄漏问题。他以实际优化案例开头,展示了将应用退出后内存占用从100多M降至20M以内的显著效果,并成功定位了InputMethodManager和MTK WebView中的具体泄漏点。 作者分享了一套行之有效的方法论:首先遵循“数据说话”和“持续改善”的原则。具体步骤上,建议优先用Android Studio的静态分析解决常见泄漏,比如Handler、未关闭的IO资源和Context使用不当等问题。对于更隐蔽的泄漏,则需要借助Leakcanary或adb命令在程序运行后进行监控,并使用MAT工具对内存快照进行深入分析。文章还详细说明了如何验证改善效果,形成闭环。 整篇文章就像一份手把手的排障指南,从原则、具体操作到验证,流程清晰。特别是对使用MAT时的关键注意事项(如关注Retained Size、排除软弱引用)的总结,对于实际解决问题很有参考价值。

IT 2016-04-02 23:13:01 / 累计浏览 2,215

对Android中的多图片异步加载的重新思考

这篇讲的是图片加载策略引发的性能反思。作者从开源中国客户端的一个实际问题出发:早期版本采用多线程并发下载图片,结果在列表加载时,图片反而出现明显的延迟和卡顿,尤其是在网络条件不佳的情况下。 核心发现直觉与效果的悖论:为什么传统观念中能提升资源利用率的并发,在这里却拖了后腿?文章用了一个生动的比喻——如同一个人同时推进两个相似项目,虽然总工时可能缩短,但单个项目完成的周期却被拉长,导致用户感知到的响应变慢了。 作者进一步剖析了 Android 系统本身的演进:在 Android 3.0 之后,AsyncTask 从默认的并发执行改为了串行执行队列。这个看似“退步”的设计,实际上是为了规避高并发下可能引发的资源耗尽与崩溃风险。在图片加载场景中,配合滚动时及时取消无效任务的机制,串行执行不仅更安全,从用户体感上看也避免了任务间的相互“干扰”,使图片能更连贯、流畅地逐张呈现。 这篇技术复盘最终指向一个启发:在移动端资源受限的环境下,技术方案的选择需要超越纸面的性能理论,紧密结合具体的使用场景和用户体验来重新审视。有时,看似“更慢”的串行,反而是通往“更快”感知的路径。

IT 2016-04-02 23:10:40 / 累计浏览 2,737

仿iPhone辅助球实现

这篇讲的是如何在Android上实现一个类似iOS辅助球的悬浮手势菜单。作者从一个很实用的角度出发,复盘了去年完成的一个个人项目,核心要解决的问题就是:如何让一个View脱离Activity,悬浮在所有界面甚至桌面上,并且能自由拖动和响应点击。 文章深入解释了两个关键的技术实现。第一,如何让Service能够显示View。作者厘清了原理,指出在Service中,通过获取系统的WindowManager服务并调用它的addView方法,就能将自定义View添加到屏幕上,从而实现全局悬浮。第二,如何实现手势交互。这里作者采用了更直接的方式,通过为View设置OnTouchListener,实时获取手指的屏幕坐标,并动态更新View的位置参数(Margin),来实现平滑的拖拽效果。 整篇文章从原理分析到核心代码一气呵成。给出的TopFloatService类代码完整展示了如何创建悬浮球、注册触摸事件监听、以及在点击时弹出菜单,思路清晰,对于想实现类似功能的开发者来说,具有很高的参考价值和实操性。

IT 2016-04-02 23:07:35 / 累计浏览 2,232

Android Studio使用过程中遇到的一些问题及解决方案

这篇讲的是作者从Eclipse迁移到Android Studio后,在Windows环境下踩到的一系列“坑”以及他摸索出的解决方案。由于项目涉及JNI编译等复杂依赖,作者采取了在Eclipse中编译JNI、在AS中引用jar和so的过渡方案,并在此过程中总结了十七个具体问题。 文章内容非常“接地气”,直指迁移过程中的核心痛点。例如,如何在build.gradle中正确配置jniLibs路径以加载SO库,如何通过`lintOptions`避免因检查过严导致的编译失败,以及如何解决多模块间的资源文件冲突。除了这些编译与配置问题,文章也覆盖了许多提升效率的设置,比如自动导包、代码格式化快捷键、Logcat颜色自定义,甚至是删除Module的正确操作流程。 作者没有空谈理论,而是将每个问题的背景、原因和修改方法都直接呈现,其中的Gradle配置片段和菜单路径对于遇到同类问题的开发者来说极具参考价值。对于正在或计划进行Eclipse到AS迁移的团队,这些经过实践验证的经验,或许比官方文档更直接有效。

IT 2016-04-02 13:44:45 / 累计浏览 3,018

启动activity的4种模式(standard、singleTop、singleTask、singleINstance)

这篇技术文章深入浅出地解析了Android开发中核心却容易混淆的四种Activity启动模式:standard、singleTop、singleTask与singleInstance。作者没有停留在概念定义,而是通过一个简单的示例应用,在小米4真机上通过命令行抓取Activity栈信息,直观展示了每种模式下Activity实例的创建与复用规则。 文章详细对比了它们的关键差异:standard模式最“勤快”,每次启动都创建新实例并入栈;singleTop则更“聪明”,若目标Activity已在栈顶就复用,避免重复创建;singleTask拥有自己独立的任务栈,启动时会清除栈内其上的Activity;而singleInstance则最为“孤僻”,确保一个Activity全局只存在一个实例,且独占一个任务栈。作者特别指出,理解这些差异对于处理应用内页面跳转、通知栏启动、甚至多任务返回栈的行为至关重要。 最后,文章也提示了实际开发中这四种模式常与Intent标志位配合使用,以实现更精细的控制。对于Android开发者来说,无论你是刚入门还是需要厘清模糊概念,这篇基于实操对比的文章都能提供清晰的指导。

IT 2016-04-02 13:42:06 / 累计浏览 4,794

启动Activity的流程(Launcher中点击图标启动)

这篇讲的是Android开发中最基础也最关键的一环:Activity是如何被启动的。作者没有泛泛而谈,而是聚焦于最常见的“Launcher桌面点击图标”这一场景,通过一个包含两个Activity(A和B)的完整案例,带你深入源码,剖析背后完整的调用流程。 文章的核心价值在于清晰的对比和串联。作者首先点明Activity启动的三种常见方式(桌面点击、代码调用、命令am start),并强调它们的底层处理逻辑是相通的。理解了其中一种,就能举一反三。 为了让你彻底看懂,文章提供了详实的“弹药”:从Activity A和B的具体Java代码、对应的XML布局,到清单文件中至关重要的`intent-filter`配置(特别是`MAIN`和`LAUNCHER`这两个标签),一应俱全。在案例中,点击A中的按钮跳转到B时,日志会明确显示出Activity生命周期的切换顺序——先执行A的`onPause`,然后才是B的`onCreate`和`onResume`,这个过程是理解Activity任务栈管理的关键。 对于想从“会用”进阶到“理解原理”的Android开发者来说,这是一次非常扎实的源码梳理。它不仅告诉你流程是怎样的,更通过可运行的案例让你亲手验证这个过程,将理论和实践紧密结合起来。

IT 2016-04-02 13:37:47 / 累计浏览 2,996

Android注解式绑定控件,没你想象的那么难

这篇讲的是如何用注解告别Android开发中繁琐的控件绑定。作者从大家熟悉的 `findViewById` 方法切入,直接点出它的痛点:方法名冗长、需要强制类型转换,随着布局复杂,初始化代码很容易变得冗余又影响可读性。 文章随后以KJFrameForAndroid框架为例,展示了如何通过自定义注解 `BindView` 来优雅地解决这个问题。核心思路很清晰:定义一个注解类,包含 `id` 和 `click` 两个属性,用于声明控件ID和点击事件。开发者只需在字段上方添加 `@BindView` 注解,一行代码就能完成绑定。 更关键的是注解的处理部分。作者解释了利用Java反射机制,在运行时遍历类的所有字段,读取 `BindView` 注解中的值,最后通过 `findViewById` 完成实际绑定。这种“声明式”的编码方式,让视图绑定变得直观且简洁,有效减少了样板代码,也让Activity的代码结构更干净。

IT 2016-04-02 13:23:15 / 累计浏览 2,074

Android EditText的使用及值得注意的地方

这篇讲的是Android开发中EditText组件的实战技巧与避坑指南。作者从实际开发经验出发,系统梳理了与EditText和输入法交互的多个关键细节。 文章核心围绕如何提升输入体验展开,提供了具体可操作的代码方案。例如,如何通过`setInputType`为不同应用场景(如词典与单词应用)设置默认的中英文输入状态;如何利用`InputMethodManager`手动控制输入法的弹出与隐藏,以配合搜索流程或响应其他窗口事件;以及如何通过`TextWatcher`监听输入内容变化,实现实时字数提示或搜索建议。 此外,文章还涉及了交互细节的优化,比如通过监听按键事件处理输入法回车按钮的确认功能,使用`setImeOptions`自定义回车按钮的文案(如“搜索”或“发送”),以及通过自定义`InputFilter`来限制用户只能输入特定字符(如纯英文或纯中文)。 这些内容覆盖了从基础设置到进阶控制的完整链条,为开发者提供了处理EditText常见场景的实用工具箱,有助于写出更健壮、更符合用户直觉的输入界面。

IT 2016-04-02 12:56:48 / 累计浏览 3,236

Android流式布局实现

这篇讲的是如何从零开始,动手实现一个Android中常见的“流式布局”(也叫标签换行布局)。作者从实际项目需求出发,聚焦于自定义ViewGroup的两个核心回调:onMeasure()和onLayout()。 摘要里重点揭示了实现的关键:在onMeasure()阶段,需要遍历所有子控件,测量它们的宽高,并以此计算出控件自身需要的总高度。而在onLayout()阶段,则根据测量结果,逐个确定每个子控件的摆放位置。最核心的逻辑在于:程序会持续累加当前行子控件的宽度,一旦发现加上下一个子控件后会超出父控件的宽度,就会触发换行操作,将下一个子控件放到下一行的起始位置。 整个实现过程清晰展示了ViewGroup如何协调测量与布局来完成复杂的子控件排列。通过理解这段代码,开发者能掌握自定义布局的基本原理,为实现更灵活的UI控件打下基础。

IT 2016-03-31 22:20:49 / 累计浏览 3,179

Android应用内多进程的使用及注意事项

这篇讲的是 Android 应用内为何以及如何使用多进程。作者从解决主进程内存压力问题出发,指出当应用处理大图片或频繁绘制时容易 OOM,仅靠 `largeHeap` 增加堆内存只是权宜之计,会影响整机效率。因此,引入了多进程方案:通过在 AndroidManifest.xml 中为组件设置 `android:process` 属性,将特定页面(如视频播放)放入独立进程,以分担主进程内存压力。 文章重点分析了使用多进程后会遇到的“坑”。由于每个进程拥有独立的内存空间,会导致三大核心问题:一是断点调试失效,堆栈不连续,通常需要临时移除 `process` 属性来调试;二是 Activity 管理逻辑(如通过 LinkedList 全局退出应用)失效,因为每个进程会独立运行 Application 的 onCreate;三是进程间无法共享内存,通信和数据共享必须借助 Bundle、AIDL 或文件等跨进程机制。 文章最后指出,虽然多进程能缓解内存问题,但这是一种“下下策”,根本之道还是在于做好应用的性能优化。

IT 2016-03-24 17:24:13 / 累计浏览 2,957

Android的Handler机制原理

Android开发中,UI线程阻塞和线程安全是两大经典难题。这篇文章从问题根源讲起:主线程负责UI交互和事件分发,一旦执行耗时操作就容易引发ANR,而子线程又不能直接更新UI。为了解决这个“两难”境地,Android引入了Handler机制作为线程间通信的桥梁。 文章核心梳理了Handler的工作流:子线程将耗时任务处理完成后,通过Handler将Message或Runnable发送到主线程的MessageQueue中;主线程则依靠Looper无限循环地取消息,再交回Handler的handleMessage方法处理,从而安全地更新界面。作者通过两个清晰的代码案例(sendMessage与postDelayed)展示了具体实现,让理论立刻落地。 整体上,这是一篇扎实的源码原理剖析。它不仅解释了Handler“是什么”,更紧扣“为什么需要”这个设计背景,将消息队列、循环器、消息对象这几个核心组件的协作关系讲得透彻明了,对于想深入理解Android异步消息处理机制的开发者来说,是一份逻辑清晰的参考资料。

IT 2016-03-23 23:32:09 / 累计浏览 2,491

Android 三大图片缓存原理、特性对比

这篇技术分析深入对比了 Android 开发中三大经典图片缓存库:Universal ImageLoader、Picasso 和 Glide。作者从源码出发,剖析了它们的整体设计流程与核心模块,如 ImageLoader 的引擎、Picasso 的调度器、Glide 的生命周期管理等,并提炼出多级缓存、高可配置性等共同优点。 文章重点在于揭示三者的关键差异:ImageLoader 以功能全面和缓存算法多样见长;Picasso 背靠 Square 生态,具备流量监控和智能网络适配,但本地缓存依赖 OkHttp;Glide 则更像媒体缓存,它深度整合 Android 生命周期,并在内存管理上做了精巧优化(如 ActiveResources 计数和缓存缩略图),默认使用 RGB_565 格式以节省内存。 通过这种从原理到特性的系统对比,文章为开发者提供了清晰的选型参考:ImageLoader 适合需要高度定制化和传统方案的项目;Picasso 在追求代码简洁与网络状态感知的场景中表现出色;而 Glide 凭借其“内存友好”特性和对生命周期的良好支持,尤其适合界面频繁刷新、媒体类型复杂的应用。

IT 2016-03-23 15:02:45 / 累计浏览 4,075

Android最方便的推送框架

这篇讲的是如何打造一个对Android开发者更友好的推送库,目标是让一个人就能完成推送功能的集成,摆脱对复杂服务器端配合和漫长测试的依赖。作者从现有推送方案的痛点出发,深入剖析了Push与Pull两种模式的底层原理、适用场景及资源消耗差异。他选择基于轮询(Pull)模式来实现,并指出了直接使用定时器可能带来的系统回收风险,转而采用AlarmManager来更稳健地调度任务。文章的核心不仅在于代码实现,更在于一套完整的优化策略:根据网络状态动态调整轮询频率,在屏幕熄灭后适时停止请求以节省电量与流量,并探讨了如何让后台服务更持久地存活,尽管在面对某些定制化系统时仍存在挑战。作者最后坦诚分享了在服务持久化问题上的探索与局限,为同样面临此难题的开发者提供了思路。

IT 2016-03-23 14:27:18 / 累计浏览 2,170

Android设置应用内文字的默认颜色和大小

这篇文章解决了一个 Android 开发中常见的主题适配问题:当未显式设置 TextView 或 Button 的文字颜色时,切换应用主题会导致文字颜色意外改变;另外,若想调整 Toast 的文字大小,通常需要重写其内部实现,颇为繁琐。 作者从 Android 主题继承机制出发,提出了一种简洁的方案:在项目的 `styles.xml` 中为应用主题(如 `AppTheme`)直接定义 `android:textSize` 和 `android:textColor` 属性,并在 `AndroidManifest.xml` 中引用该主题。这样,所有未单独设置文字样式属性的 View,都会自动继承主题中指定的颜色和大小,包括 Toast。 这个方案的核心在于利用主题的全局覆盖特性,以最小代码成本统一了应用内文字的默认视觉表现,避免了在每个 View 上重复定义或处理意外的主题变更。需要注意的是,该设置仅作为默认值生效,如果某个 View 已经通过代码或 XML 明确指定了文字颜色或大小,将优先采用其自身设置。