Android开发艺术探索
1 Activity的生命周期和启动模式
典型情况下生命周期
异常情况下生命周期
启动模式
标准模式
栈顶复用模式
栈内复用模式
单实例模式
Activity的Flags
IntentFilter的匹配规则
2 IPC机制
进程间通信
Serializanle
Parcelable
Binder
3 View的事件体系
事件分发机制
事件分发机制
点击事件就是MotionEvent 事件分发其实就是对MotionEvent事件的分发
三大方法
dispatchTouchEvent 分发
onInterceptTouchEvent 拦截
onTouchEvent 消费
事件传递顺序 Activity Window View
对于ViewGroup 点击事件产生后 就会调用dispatchTouchEvent 然后调用onInterceptTouchEvent
如果返回true 表示要拦截该事件 就会调用onTouchEvent
如果返回false 表示不看就 则该事件就会传递到其子元素中
4 View的工作原理
View的工作流程
onMeasure 为整个View树计算实际的大小 设置实际的宽高
每个View控件的实际宽高由父视图和本身视图决定
onLayout 根据子视图大小布局参数 将View放到合适的位置上
onDraw 绘制图像 首先绘制背景 再调用onDraw绘制视图本身 如果View是ViewGroup
调用dispatch绘制子视图 最后绘制滚动条
自定义View
继承View重写onDraw 用于实现一些不规则的效果
继承ViewGroup派生特殊的Layout 用于实现自定义布局
5 RemoteViews
6 Drawable
7 Android动画
View动画 通过对场景里的对象做图像变换 平移 缩放 旋转 透明度从而产生动画效果
帧动画 通过顺序播放一系列图像从而产生动画效果
属性动画 API11 动态的改变对象的属性产生动画效果
8 Window WindowManager
9 四大组件工作机制
10 Android的消息机制
Handler机制
Handler通过调用sendMessage把消息放在消息队列MessageQueue中
Looper负责把消息从消息队列中取出来 重新再交给Handler进行处理
11 线程和线程池
AsyncTask
封装了线程池和Handler 方便在子线程中更新UI
HandlerThread
具有消息循环的线程 内部使用Handler
实现方式是run中通过Looper.prepare来创建消息队列 并通过Looper.loop来开启消息循环
IntentService
特殊的Service 封装了HandlerThread和Handler 用于执行后天耗时的任务 任务执行后自动停止
ThreadPoolExecuter 线程池
重用线程池中线程 避免因为线程的创建销毁带来的性能开销
有效控制线程池最大并发数 避免线程之间抢占资源导致的阻塞
能够对线程进行简单管理
构造方法参数
corePoolSize 核心线程数
maxmunPoolSize 最大线程数
keepAliveTime 超时时长
unit 时间单位
workQueue 任务队列
threadFactory 线程工厂
四类线程池
FixedThreadPool
CachedThreadPool
ScheuledThreadPool
SingleThreadPool
12 Bitmap的加载和Cache
Bitmap加载和缓存
LruCache 内存缓存
内部采用LinkedHashMap以强引用方式存储外界缓存对象
强引用 直接的对象引用
软引用 系统内存不足时该对象被gc回收
弱引用 此对象随时会被gc回收
DiskLruCache 硬盘缓存
13 综合技术
CrashHandler
multidex解决方法数越界
动态加载技术
资源访问
Activity生命周期管理
ClassLoader管理
反编译初步
14 JNI和NDK
JNI Java本地接口 方便Java调用C C++等本地代码所封装的一层接口
NDK Android所提供的一个工具集合 通过NDK可以在Android中更加方便
的通过JNI来访问本地代码
JNI的开发流程
在Java中声明native方法
编译Java源文件得到class文件 然后通过javah导出JNI的头文件
实现JNI方法
编译so库并在Java中调用
NDK开发流程
下载并配置NDK
创建一个Android项目并声明所需的native方法 java文件 System.loadLibrary
实现Android项目所声明的native方法 test.cpp Android.mk Application.mk
通过ndk-build命令编译产生so库
JNI的数据类型和类型签名
JNI调用Java方法的流程
15 Android性能优化
性能优化
布局优化
删除布局中无用的控件和层级 选择性能较低的ViewGroup 避免过度绘制
include标签 重用指定的布局文件
merge标签和include标签一起使用减少布局层级
ViewStub 按需加载所需的布局文件
绘制优化
View的onDraw避免执行大量的操作
不要创建新的局部对象 不要做耗时任务
内存泄漏优化
静态变量导致的内存泄漏
单例模式导致
属性动画无限循环
补充
资源对象没有关闭 如查询数据库没有关闭游标
构造Adapter没有使用convertView
Bitmap在不使用时未调用recycle释放内存
Context逃逸
注册没有取消 如动态注册广播在Activity销毁没有反注册
集合对象未清理
Activity中使用非静态内部类 并开启一个长时运行的线程
由于内部类持有Activity引用 导致Activity无法回收
Handler内存泄漏
类的静态变量持有大数据对象
非静态内部类存在静态实例
响应速度优化 避免在主线程中做耗时操作
ANR
Activity 5秒内无法响应输入操作
BroadcastReceiver 10m秒内还未执行完操作
Servcice 20秒内未完成相关处理
定位 开发机器上查看traces.txt日志
避免 使用子线程处理耗时IO操作
解决办法
Java多线程
AsyncTask
Handler机制
HandlerThread
IntentService
ListView优化
采用ViewHolder并避免在getView中执行耗时操作
根据列表的滑动状态来控制任务的执行频率
开启硬件加速使ListView滑动更流程
Bitmap优化
通过BitmapFactory.Options来根据需要对图片进行采样
配置inSampleSize参数
线程优化
采用线程池
MAT 内存泄露分析工具
提供程序可维护性