本文主要讲解 ApiDemos 中的 AlertDialog 章,介绍 AlertDialog 的使用和部分方法实现原理。本文是 ApiDemos 分析系列的第一篇,也是笔者第一次尝试以自己的角度分析源码。

建造者模式

AlertDialog 最明显的特点就是使用了建造者模式,有关该设计模式的介绍请移步:[Android] 设计模式-建造者模式

showDialog 显示对话框的原理

showDialog 是什么,它是 Activity 提供的显示 Dialog 的简便方法,封装在 Activity 中。showDialog() 方法 Api level 1 中被添加, Api level 13(Honeycomb 3.0)被废弃。

我们可以推测:

  1. AlertDialog 是 Activity 的一部分
  2. Android 代码逐渐朝着低耦合发展

简单用法

原理分析

下图是调用过程图

showDialog 调用过程

如图所示,上一层为 Activity,下一层为自己定义的 Activity 的派生类。

其中:

第1步:给按钮设置点击事件,开始执行 showDialog(id) 方法
第3步:showDialog(id, args) 方法维护了一个缓存池。

每一个 Activity 都会创建一个 Dialog 缓存池,同一个 Activity 只创建一份不同 ID 类型的 Dialog,目的是提高效率。其中 onPrepareDialog(id, md.mDialog, args) 的作用是绑定 Dialog和Activity 。

也就是说,AndroidSDK 封装了 Dialog 对象的 维护 ,把 创建使用 这两步交给使用者去实现。只有当使用者实现了这两部,整个流程才算完结。这无疑是高度耦合的。所以在高版本,这种做法已经被废弃。

AlertController 和 AlertParams

AlertController 和 AlertParams 这两个类是 AlertDialog 和核心,AlertDialog 的大部分功能都通过 AlertController 实现,而 AlertParams 包含了对话框所需的各种元素(Title、 Message、 CheckedItems、 是否多选、四个 Padding 、各种监听…)

由于这两个类是 Android 内部类,无法用 Eclipse 跟踪,所以用 source insight 打开,在 com.android.internal.app 包下。

按钮事件处理器: ButtonHandler

以上可以看出:

  1. Dialog 内部通过 Handler+Message 实现了事件的处理,
  2. 内部类 ButtonHandler 持有外部对象成员 mDialog 的弱引用,以避免内存泄露。

AlertParams 设置 View 和 Title、Message 过程

不论设置 Title 还是 Content 之前,都判断是否存在 CustomXXView (自定义的 View ),没有自定义 View 才进步设置 Title 、Message

其他方法均为设置背景、设置 ICON 以及各种解析资源。就不再列举。

setIconAttr 的原理分析

不知是否记得 AlertDialog 提供了 setIconAttr 方法方便设置对话框的图标。

示例代码如下:

Eclipse 中按住 Ctrl+左键 跟踪后发现,该属性定义在:

内容为:

表示该属性指向的内容为引用类型,可以是:图片、文本、XML 文件

跟踪后可看到:

P.mContext 指向 Activity 实例

以上代码可知:

  1. 该 AttrsID 和 Android 系统当前 Theme 下的图片资源存在映射关系。
  2. ContextThemeWrapper 父类负责根据 AttrsID 找到当前 Theme 中对应的 ICON。
  3. TypedValue 对象存放解析后的图片资源。

技巧总结:

SparseArray

showDialog() 使用维护 Dialog , 我们可以借鉴,并用在自己的项目中。
如:
1. BaseActivity 中使用 SparseArray 维护 Activity 集合,以便统一退出。
2. BaseViewHolder 中,用 SparseArray 保存 findViewById 的结果

低耦合的思想

在开发过程中,我们尽量降低组件之间的耦合度,方便代码的维护和升级。(需要不断的积累、总结)

参考

发表评论

电子邮件地址不会被公开。 必填项已用*标注