Android开发艺术探索——Android性能优化

这是我在学习过程中总结的知识
目的是希望日后回来看或者需要用的时候可以 一目了然 # 的回顾、巩固、查缺补漏
不追求详细相当于书本的精简版或者说是导读(想看详细的直接对应翻书),但会尽力保证读者都能快速理解和快速使用(随理解加深会总结的更加精简),但必要时会附上一些较详细解释的链接
脚注是空白的:表示还没弄懂的知识,了解后会添加

本章介绍

  • 常见的性能优化方法
  • 提供程序的可维护性和可扩展性的思想

15.1 Android的性能优化方法

15.1.1 布局优化

核心思想——减少布局文件的层级

  • 删除布局中无用的空间和层级
  • 使用性能较低的ViewGroup,比如LinearLayout比RelativeLayout简单,耗能少
  • 采用include标签(布局重用)、merge标签(结合include,减少布局层级)和ViewStub(提供按需加载)

merge

两个竖直方向的LinearLayout,可以用merge去除被包含的LinearLayout

ViewStub

ViewStub继承了View
在网络异常时的界面,就没必要加载整个界面

15.1.2 绘制优化

是指View的onDraw方法要避免执行大量的操作

  1. onDraw中不要创建新的布局对象
  2. onDraw不要做耗时的任务,也不能是成千上万次的循环操作

15.1.3 内存泄露的优化

内存泄露的优化分为两个方面

  • 开发过程中避免写出有内存泄漏的代码
  • 通过分析工具比如MAT来找出潜在的内存泄露然后解决

1. 静态变量导致的内存
这些静态变量会导致Activity无法正常销毁

    private static Context sContext;
    private static View sView;

    private Button mButton;

    @SuppressLint("NewApi")
    @SuppressWarnings("deprecation")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        sContext = this;
		sView = new View(this);
		}

2. 单例模式导致的内存泄露
首先提供一个单例模式的类,可以接收外部的注册并将外部的监听器存储起来

package com.ryg.chapter_15.manager;

import java.util.ArrayList;
import java.util.List;

public class TestManager {

    private List<OnDataArrivedListener> mOnDataArrivedListeners = new ArrayList<OnDataArrivedListener>();

    private static class SingletonHolder {
        public static final TestManager INSTANCE = new TestManager();
    }

    private TestManager() {
    }

    public static TestManager getInstance() {
        return SingletonHolder.INSTANCE;
    }

    public synchronized void registerListener(OnDataArrivedListener listener) {
        if (!mOnDataArrivedListeners.contains(listener)) {
            mOnDataArrivedListeners.add(listener);
        }
    }

    public synchronized void unregisterListener(OnDataArrivedListener listener) {
        mOnDataArrivedListeners.remove(listener);
    }

    public interface OnDataArrivedListener {
        public void onDataArrived(Object data);
    }
}

现在让Activity实现OnDataArrivedListener接口并向TestManager注册监听,但是下面代码由于缺少解注册的操作所以会引起内存泄露
原因是Activity的对象被单例模式的TestManager所持有,而单例模式的特点是其生命周期和Application保持一致,因此Activity对象无法被及时释放

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        sContext = this;
		TestManager.getInstance().registerListener(this);

3. 属性动画导致的内存泄露
属性动画中有一类无限循环的动画,如果没有在onDestroy中去停止,那么动画会一直播放下去.这个时候Activity的View 被动画持有,而View又持有了Activity,最终Activity无法被释放
解决方法是调用animator.cancel()方法

15.1.4 响应速度优化和ANR日志分析

Android规定,Activity如果5秒钟内无法响应屏幕触摸事件或者键盘输入事件就会出现ANR
BroadcastReceiver如果10秒钟之内还未执行完操作也会出现ANR
当一个进程发生了ANR以后,系统会在/data/anr目录下创建一个traces.txt文件,我们需要分析这个文件找出问题

15.1.5 ListView和Bitmap优化

ListView

  • 首先采用ViewHolder并避免在getView中执行耗时操作
  • 根据列表的滑动状态来控制任务的执行频率,比如快速滑动时不要开启大量的异步任务
  • 尝试开启硬件加速

Bitmap

  • 通过BitmapFactory.Options来根据图片采样缩放

15.1.6 线程优化

  • 使用线程池避免程序中存在大量的Thread
  • 线程池控制线程并发,放置出现阻塞现象

15.1.7 一些性能优化建议

  • 避免创建过多对象
  • 不要过多使用枚举
  • 常量使用static final 来修饰
  • 使用一些Android特有的数据结构,比如SparseArray和Pair等,性能更好
  • 适当使用软引用和弱引用
  • 采用内存缓存和磁盘缓存’
  • 尽量采用静态内部类,避免潜在的由于内部类导致的内存泄露

15.2 内存泄露分析之MAT工具

15.3 提高程序的可维护性

  • 私有成员以m开头
  • 静态成员以s开头
Android开发艺术探索》是一本Android进阶类书籍,采用理论、源码和实践相结合的方式来阐述高水准的Android应用开发要点。《Android开发艺术探索》从三个方面来组织内容。第一,介绍Android开发者不容易掌握的一些知识点;第二,结合Android源代码和应用层开发过程,融会贯通,介绍一些比较深入的知识点;第三,介绍一些核心技术和Android性能优化思想。 《Android开发艺术探索》侧重于Android知识的体系化和系统工作机制的分析,通过《Android开发艺术探索》的学习可以极大地提高开发者的Android技术水平,从而更加高效地成为高级开发者。而对于高级开发者来说,仍然可以从《Android开发艺术探索》的知识体系中获益。 《Android开发艺术探索》是一本Android进阶类书籍,采用理论、源码和实践相结合的方式来阐述高水准的Android应用开发要点。《Android开发艺术探索》从三个方面来组织内容。第一,介绍Android开发者不容易掌握的一些知识点;第二,结合Android源代码和应用层开发过程,融会贯通,介绍一些比较深入的知识点;第三,介绍一些核心技术和Android性能优化思想。, 《 Android开发艺术探索》侧重于Android知识的体系化和系统工作机制的分析,通过《Android开发艺术探索》的学习可以极大地提高开发者的Android技术水平,从而更加高效地成为高级开发者。而对于高级开发者来说,仍然可以从《Android开发艺术探索》的知识体系中获益。
本书是一本Android进阶类书籍,采用理论、源码和实践相结合的方式来阐述高水准的Android应用开发要点。本书从三个方面来组织内容。第一,介绍Android开发者不容易掌握的一些知识点;第二,结合Android源代码和应用层开发过程,融会贯通,介绍一些比较深入的知识点;第三,介绍一些核心技术和Android性能优化思想。 第1章 Activity的生命周期和启动模式 1 1.1 Activity的生命周期全面分析 1 1.1.1 典型情况下的生命周期分析 2 1.1.2 异常情况下的生命周期分析 8 1.2 Activity的启动模式 16 1.2.1 Activity的LaunchMode 16 1.2.2 Activity的Flags 27 1.3 IntentFilter的匹配规则 28 第2章 IPC机制 35 2.1 Android IPC简介 35 2.2 Android中的多进程模式 36 2.2.1 开启多进程模式 36 2.2.2 多进程模式的运行机制 39 2.3 IPC基础概念介绍 42 2.3.1 Serializable接口 42 2.3.2 Parcelable接口 45 2.3.3 Binder 47 2.4 Android中的IPC方式 61 2.4.1 使用Bundle 61 2.4.2 使用文件共享 62 2.4.3 使用Messenger 65 2.4.4 使用AIDL 71 2.4.5 使用ContentProvider 91 2.4.6 使用Socket 103 2.5 Binder连接池 112 2.6 选用合适的IPC方式 121 第3章 View的事件体系 122 3.1 View基础知识 122 3.1.1 什么是View 123 3.1.2 View的位置参数 123 3.1.3 MotionEvent和TouchSlop 125 3.1.4 VelocityTracker、GestureDetector和Scroller 126 3.2 View的滑动 129 3.2.1 使用scrollTo/scrollBy 129 3.2.2 使用动画 131 3.2.3 改变布局参数 133 3.2.4 各种滑动方式的对比 133 3.3 弹性滑动 135 3.3.1 使用Scroller 136 3.3.2 通过动画 138 3.3.3 使用延时策略 139 3.4 View的事件分发机制 140 3.4.1 点击事件的传递规则 140 3.4.2 事件分发的源码解析 144 3.5 View的滑动冲突 154 3.5.1 常见的滑动冲突场景 155 3.5.2 滑动冲突的处理规则 156 3.5.3 滑动冲突的解决方式 157 第4章 View的工作原理 174 4.1 初识ViewRoot和DecorView 174 4.2 理解MeasureSpec 177 4.2.1 MeasureSpec 177 4.2.2 MeasureSpec和LayoutParams的对应关系 178 4.3 View的工作流程 183 4.3.1 measure过程 183 4.3.2 layout过程 193 4.3.3 draw过程 197 4.4 自定义View 199 4.4.1 自定义View的分类 200 4.4.2 自定义View须知 201 4.4.3 自定义View示例 202 4.4.4 自定义View的思想 217 第5章 理解RemoteViews 218 5.1 RemoteViews的应用 218 5.1.1 RemoteViews在通知栏上的应用 219 5.1.2 RemoteViews在桌面小部件上的应用 221 5.1.3 PendingIntent概述 228 5.2 RemoteViews的内部机制 230 5.3 RemoteViews的意义 239 第6章 Android的Drawable 243 6.1 Drawable简介 243 6.2 Drawable的分类 244 6.2.1 BitmapDrawable 244 6.2.2 ShapeDrawable 247 6.2.3 LayerDrawable 251 6.2.4 StateListDrawable 253 6.2.5 LevelListDrawable 255 6.2.6 TransitionDrawable 256 6.2.7 Ins
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值