Apps nowadays are all about fancy animations, complex transitions and custom views, and the user experience must be intuitive and similar as possible in any device. These patterns gonna help you build an app that’s smooth, responsive, and uses as little battery as possible, it covers micro-optimizations that can improve overall app performance.
时下应用程序都需要花哨的动画,过渡的复杂和自定义视图,而且用户体验必须是直观,尽可能在任何设备都是相似的。这些模式会帮你建立一个应用程序,是平稳,反应灵敏,并在使用时尽可能的减少电池消耗,它涵盖了细节优化,可以提高整体应用性能。
Patterns to avoid bad performance
避免不良表现的模式
- main Thread
- 避免阻塞主线程(避免ANR)
- unnecessary invalidations that may trigger
- 避免无效的绑定无用的组件
- RelativeLayouts
- RelativeLayouts
- weights in LinearLayouts ( Cz each child needs to be measured twice)
- LinearLayouts 的weight属性 (他的每个子视图在显示时都会测量两次)
- views not properly
- 避免使用不正确的自定义视图
- Unnecessary
- 避免创建无效的对象
- Static Final
- Static Final15%-20% )
- Primitives (Integer vs Float 2x slower)
- Float 比 Integer 慢两倍?注:感觉有歧义)
- Getters/Setters
- Getters/Setters(字段访问速度会快3倍)
- Loop
- 使用增强的for循环语法
- Package
- Package去代替私有内部类
- Native
- Native时要小心(NDK、JNI的Native)
Patterns for Custom views
自定义视图模式
- KISS)
- 尽可能的保持简单(KISS原则)
- merge
- 在根layout中使用merge(避免扩展性的ViewGroup)
- include
- 使用include标签
- unnecessary
- 避免无用的layout
- allocations or heavy operations in OnDraw
- 不要在OnDraw中进行复杂操作及计算
- unnecessary calls to invalidate()
- 移除不必要的invalidate()
- ViewGroup
- 考虑创建属于你自己的ViewGroup
- RecyclerView (replaces ListView and GridView)
- RecyclerView (代替ListView和GridView)
Patterns to avoid memory churn
- allocate a large amount of unnecessary
- Immutable classes: String
- Autoboxing: Integer, Boolean..
- Object Pools and caches to reduce churn
- enums (a single reference to an enum constant occupy 4 bytes)
Patterns to avoid memory leaks
避免内存泄漏的模式
- contexts
- 不要泄漏内部类环境
- views
- 不要在Activity中泄漏View
- static inner classes over non static
- 尽量使用静态内部类
- WeakHashmap as cache. Only the keys are WeakReference
- WeakHashmap 作为缓存,这样只有Key是弱引用
Patterns for CPU
CPU模式
- multi-pass
- 不要窝多通道布局(注:不太明白)
- complex data when needed
- 当用的时候再去懒散的计算复杂数据(Lazily? 懒惰的意思?难道是随用随算的意思)
- heavy computational results for re-use
- 重用缓存重计算结果
- RenderScript
- 考虑RenderScript性能
- off of the main thread
- 保证主线程是无工作的状态(注:确保主线程能随时工作)
Patterns to avoid Overdraw
避免重绘模式
- drawables
- 简化你的绘制
- nine patch
- 用9-path绘制透明部分
- alpha
- 谨慎的给View设置透明度
- unused background from your views
- 移除无用的背景色
Patterns for Bitmaps
bitmap模式
- bitmaps to the desire size: BitmapFactory.Options(inSampleSize, inDensity, inTargetDensity)
- 解码bitmap到希望的大小,BitmapFactory.Option
- memory
- 内存中的bitmap是准备显示的(bitmap的缓存)
- scale if you don’t need to (createScaledBitmap(btimap, int, int))
- 如果你不需要bitmap就不要创建设定尺寸(用createScaledBitmap)
- LRU
- 用LRU缓存
Patterns for Services
Service模式
- service unless it’s actively performing a job. Also be careful to stop service it when its work is done
- 注意停止你的Service除非他还在工作。当他工作结束时也要注意去停止Service
- service process in running. Then the RAM used by the service can’t be used by anything else or paged out
- 系统倾向于保持service的运行,当内存被service占用而不能被其他组件使用或换出时
- limit the lifespan of your service is to use an IntentService, which finishes itself as soon as it’s done handling the intent that started it
- 最好的方式是限制你的service的寿命(生命周期)而去使用IntentService,当他处理完启动Intent后会尽可能快的结束自己。
- service running when it’s not needed is one of the worst memory
- 保留一个不必要的service运行是一个糟糕的Android app内存管理失误
Patterns for Threads
线程模式
- run() method use Process.setThreadPriority() withTHREAD_PRIORITY_BACKGROUND. This approach reduces resource competition between the Runnable object’s thread and the UI thread.
- 在一个线程的run()方法使用Process.setThreadPriority()withTHREAD_PRIORITY_BACKGROUND。这种方法减少了Runnable对象的线程和UI线程之间的资源竞争
- lower priority this way, then the thread could still slow down your app because it operates at the same priority as the UI thread
- 如果没有线程设置为较低的优先级这种方式,那么线程会拖慢你的app,因为默认普通线程的操作权限和UI线程是一样的
- Stores the current Thread reference in your app, so that you want to interrupt the Thread later on. e.g: On network failure you can cancel that thread operation.
- 存储在您的应用程序当前线程引用,以至于以后可以中断线程。例如:在网络出现故障,你可以取消线程操作。
Patterns to avoid ARNs
避免无响应模式
- UI thread do as little work as possible
- 在UI线程尽可能少的执行任务
- work in the background in response to user input, show that progress is being made (such as with a ProgressBar in your UI).
- 如果你的app正在后台相应用户的输入,让用户看到通讯框(转圈圈)
- Systrace and Traceview to determine bottlenecks in your app’s responsiveness.
- 使用性能工具,如Systrace和Traceview以确定您的应用程序的响应能力的瓶颈。
- time-consuming initial setup phase, consider showing a launch screen or rendering the main view as quickly as possible, indicate that loading is in progress and fill the information asynchronously.
- 如果你的应用有一个耗时的初始设置阶段,考虑呈现出启动屏幕或尽可能快地渲染主视图,显示加载中并异步填充信息