本文共 2984 字,大约阅读时间需要 9 分钟。
Android 开发核心知识点探解
Activity、Window、View 三者如何协同构建用户界面
Activity、Window、View 三者是Android UI组件体系的三大核心构件,它们各自承担不同的角色,协同工作以实现用户界面的显示和交互。
- Activity:作为应用程序的主控件,负责管理窗口的生命周期和状态。它是用户与应用程序交互的入口,控制整个应用程序的运行流程。
- Window:承载UI界面的容器,负责管理视图的布局和显示。Window类似于传统操作系统中的窗口,负责绘制界面并处理用户输入。
- View:是用户界面中可视化的元素,包括按钮、文本、图像等。View类是Android UI系统的基础构件,负责绘制和交互。
这三个构件通过LayoutInflater(剪刀工具)将布局文件转换为实际的UI视图,共同完成界面的绘制和展示。
Fragment 的特点及使用体验
Fragment是一种轻量级的UI组件,旨在将Activity的界面拆分成多个独立的模块,提高开发效率和代码复用性。
模块化设计:Fragment可以独立存在,作为Activity的一部分组成,支持多个Fragment同时存在于同一Activity中。 灵活组装:Fragment可以在运行时动态添加、删除或替换,支持多种组合方式,适用于多样化的UI需求。 生命周期管理:Fragment具有独立的生命周期,可以响应用户事件和状态变化,支持数据保存和恢复。 代码复用:Fragment内部可以封装自定义逻辑,适用于重复使用的UI逻辑和功能模块。 踩过的坑:
- 重叠:需谨慎管理Fragment的添加和移除,避免UI状态混乱。
- 注解新API:在低版本SDK上使用新API时需借助兼容包,确保兼容性。
- 数据初始化: Fragment生命周期中需谨慎管理数据初始化,避免Commit操作在onSaveInstanceState后执行。
- 事务管理: Fragment事务操作需谨慎处理,避免入栈出栈逻辑错误。
低版本SDK实现高版本API
在某些情况下,高版本API在低版本SDK中不存在,需手动实现或通过兼容包适配。
使用兼容包:如Fragment、Notification等API在v4兼容包中有替代实现,需根据版本判断使用兼容包或原API。 手动实现:对于没有兼容包支持的API,需自行实现或在低版本SDK中去除该功能。 版本检测:使用@TargetApi注解控制特定版本的API使用,避免编译错误。 废弃API:尽量避免使用已废弃API,防止兼容性问题。
Activity的启动模式与内存管理
Activity的启动模式
Activity的启动模式主要通过AndroidManifest.xml配置控制,常见模式包括:
- 标准模式:默认模式,支持多个Activity并存。
- SingleTop:仅保留栈顶的Activity,适用于书签、聊天等场景。
- SingleTask:将指定Activity设为唯一任务,适用于主界面。
- SingleInstance:通过intent-filter控制唯一性,常用于耗内存的Activity(如闹钟)。
内存管理
每个应用程序由Android为其分配内存资源,最大值根据配置决定。内存泄露会导致OOM,需注意以下几点:
对象复用:通过ListView、RecyclerView等使用convertView复用UI元素,减少对象创建。 图片管理:使用Bitmap的inSampleSize和decodeFormat优化图片加载,避免大图导致OOM。 对象池技术:通过LRU机制管理Bitmap、View等对象,确保内存利用率。 避免内存抖动:在onDraw方法中避免频繁创建对象,减少GC压力。
ANR问题的分析与解决方案
ANR(Application Not Responding)通常由主线程阻塞导致,需重点关注以下场景:
IO/网络操作:需在子线程执行,避免阻塞主线程。 耗时计算:自定义控件的onDraw方法中避免复杂计算,减少内存抖动。 BroadCastReceiver:确保在10秒内完成处理,减少异步化处理。 Service耗时操作:在子线程执行耗时任务,避免阻塞主线程。 AsyncTask使用:确保AsyncTask执行在子线程,避免UI阻塞。
内存泄露的防范策略
减少对象占用:使用ArrayMap、SparseArray等高效数据结构替代HashMap。 避免大图加载:使用inSampleSize压缩图片,减少内存占用。 对象池技术:通过LRU机制管理 Bitmap、View等对象,确保内存利用率。 避免内存抖动:在onDraw方法中避免频繁创建对象,减少GC压力。 优化代码:避免在onDraw方法中创建对象,减少内存抖动。
Service与Activity间通信方式
Service和Activity之间可以通过多种方式通信:
Binder:通过IBinder接口实现远程过程调用,适用于简单数据传递。 广播:通过发送广播实现异步通信,适用于不需要实时响应的场景。
Android各版本API的区别
了解不同版本API的特性有助于开发兼容性代码:
- 3.0/4.0:引入Material Design设计理念,优化UI组件。
- 4.4:性能优化,改进内存管理。
- 5.0:引入向量动画、直接布局API等新特性。
- 6.0/7.0:多任务窗口、悬停效果等新功能。
RequestLayout、onLayout、onDraw与drawChild的区别
RequestLayout():触发Measure和Layout,决定View的大小和位置。 onLayout():为ViewGroup内部子View布局,调用子View的onLayout。 onDraw():绘制View自身,ViewGroup需调用子View的onDraw。 drawChild():绘制ViewGroup中的子View,按顺序执行。
invalidate()与postInvalidate()的区别
- invalidate():在主线程刷新视图,立即生效。
- postInvalidate():在子线程发送消息,延迟刷新,适用于非UI线程调用。
Android动画框架的实现原理
Android动画框架通过Canvas进行绘制,实现透明度、缩放等效果。所有动画操作都通过View的draw方法完成,动画效果通过矩阵变换实现。
内存分配与优化
Android为每个应用程序分配的内存大小根据手机型号和版本而定,常见值为64M/32M。内存泄露是导致OOM的主要原因,需注意以下优化点:
减少对象占用:使用ArrayMap、SparseArray等高效数据结构。 优化图片加载:使用inSampleSize压缩图片,减少内存占用。 复用UI元素:通过ListView、RecyclerView等实现View的复用。 优化自定义控件:避免在onDraw方法中频繁创建对象。
Service与Activity通信
Service与Activity之间的通信可通过Binder实现,支持远程方法调用和数据传递,适用于复杂场景。
如需获取更多技术内容,请扫码关注!
转载地址:http://eioyz.baihongyu.com/