什么是Buidler模式呢?就是将一个复杂对象的构建与它的表示分离,使得相同的构建过程能够创建不同的表示.Builder模式是一步一步创建一个复杂的对象,它同意用户能够仅仅通过指定复杂对象的类型和内容就能够构建它们.

那么要为何使用Buidler呢?

是为了将构建复杂对象的过程和它的部件分开由于一个复杂的对象,不但有非常多大量组成部分,如AlertDialog对话框,有非常多组成部件,比方Tittle,Message,icon,PositiveButton等等,但远不止这些,怎样将这些部件装配成一个AlertDialog对话框呢,这个装配程可能也是一个非常复杂的步骤,Builder模式就是为了将部件和组装过程分开。通俗点说,就是我先分开生产好各个组件,然后交由还有一个类去组装这些组件。

怎样使用?

我们来看一下Android内部关于AlertDialog.Builder的源代码便能够知晓。

public class AlertDialog extends Dialog implements DialogInterface {
// Controller, 接受Builder成员变量P中的各个參数
private AlertController mAlert; // 构造函数
protected AlertDialog(Context context, int theme) {
this(context, theme, true);
} // 4 : 构造AlertDialog
AlertDialog(Context context, int theme, boolean createContextWrapper) {
super(context, resolveDialogTheme(context, theme), createContextWrapper);
mWindow.alwaysReadCloseOnTouchAttr();
mAlert = new AlertController(getContext(), this, getWindow());
} // 实际上调用的是mAlert的setTitle方法
@Override
public void setTitle(CharSequence title) {
super.setTitle(title);
mAlert.setTitle(title);
} // 实际上调用的是mAlert的setCustomTitle方法
public void setCustomTitle(View customTitleView) {
mAlert.setCustomTitle(customTitleView);
} public void setMessage(CharSequence message) {
mAlert.setMessage(message);
} // AlertDialog其它的代码省略 // ************ Builder为AlertDialog的内部类 *******************
public static class Builder {
// 1 :该类用来存储AlertDialog的各个參数, 比如title, message, icon等.
private final AlertController.AlertParams P; /**
* Constructor using a context for this builder and the {@link AlertDialog} it creates.
*/
public Builder(Context context) {
this(context, resolveDialogTheme(context, 0));
} public Builder(Context context, int theme) {
P = new AlertController.AlertParams(new ContextThemeWrapper(
context, resolveDialogTheme(context, theme)));
mTheme = theme;
} // 2:设置各种參数到P
public Builder setTitle(CharSequence title) {
P.mTitle = title;
return this;
} public Builder setMessage(CharSequence message) {
P.mMessage = message;
return this;
} public Builder setIcon(int iconId) {
P.mIconId = iconId;
return this;
} public Builder setPositiveButton(CharSequence text, final OnClickListener listener) {
P.mPositiveButtonText = text;
P.mPositiveButtonListener = listener;
return this;
} public Builder setView(View view) {
P.mView = view;
P.mViewSpacingSpecified = false;
return this;
} // 3 : 构建AlertDialog, 传递參数
public AlertDialog create() {
// 调用new AlertDialog构造对象, 而且将參数传递个体AlertDialog
final AlertDialog dialog = new AlertDialog(P.mContext, mTheme, false);
// 5 : 将P中的參数应用的dialog中的mAlert对象中
//这一步是核心方法我们等下看源代码继续讲
P.apply(dialog.mAlert);
dialog.setCancelable(P.mCancelable);
if (P.mCancelable) {
dialog.setCanceledOnTouchOutside(true);
}
dialog.setOnCancelListener(P.mOnCancelListener);
if (P.mOnKeyListener != null) {
dialog.setOnKeyListener(P.mOnKeyListener);
}
return dialog;
}
public AlertDialog show() {
//6:显示dialog
AlertDialog dialog = create();
dialog.show();
return dialog;
}
} }

从上面的源代码中我们能够看到,对话框的构建是通过Builder来设置AlertDialog中的title, message, button等參数, 这些參数都存储在类型为AlertController.AlertParams的成员变量P中,AlertController.AlertParams中包括了与之相应的成员变量。在调用Builder类的create函数时才创建AlertDialog, 而且将Builder成员变量P中保存的參数应用到AlertDialog的mAlert对象中,最后调用dialog.show方法显示对话框。

如今我们再来看看即P.apply(dialog.mAlert)代码段。我们看看apply函数的实现 。

public void apply(AlertController dialog) {
if (mCustomTitleView != null) {
dialog.setCustomTitle(mCustomTitleView);
} else {
if (mTitle != null) {
dialog.setTitle(mTitle);
}
if (mIcon != null) {
dialog.setIcon(mIcon);
}
if (mIconId >= 0) {
dialog.setIcon(mIconId);
}
if (mIconAttrId > 0) {
dialog.setIcon(dialog.getIconAttributeResId(mIconAttrId));
}
}
if (mMessage != null) {
dialog.setMessage(mMessage);
}
if (mPositiveButtonText != null) {
dialog.setButton(DialogInterface.BUTTON_POSITIVE, mPositiveButtonText,
mPositiveButtonListener, null);
}
if (mNegativeButtonText != null) {
dialog.setButton(DialogInterface.BUTTON_NEGATIVE, mNegativeButtonText,
mNegativeButtonListener, null);
}
if (mNeutralButtonText != null) {
dialog.setButton(DialogInterface.BUTTON_NEUTRAL, mNeutralButtonText,
mNeutralButtonListener, null);
}
if (mForceInverseBackground) {
dialog.setInverseBackgroundForced(true);
}
// For a list, the client can either supply an array of items or an
// adapter or a cursor
if ((mItems != null) || (mCursor != null) || (mAdapter != null)) {
createListView(dialog);
}
if (mView != null) {
if (mViewSpacingSpecified) {
dialog.setView(mView, mViewSpacingLeft, mViewSpacingTop, mViewSpacingRight,
mViewSpacingBottom);
} else {
dialog.setView(mView);
}
}
}

实际上就是把P中的參数挨个的设置到AlertController中, 也就是AlertDialog中的mAlert对象。从AlertDialog的各个setter方法中我们也能够看到,实际上也都是调用了mAlert相应的setter方法。
       综上看完上面源代码之后我们就能够发现,怪不得我们平时调用对话框的时候能够直接使用,AlertDialog dialog = new AlertDialog(P.mContext, mTheme, false);不用Alert.Builder方法创建也能够,由于其本质是一样的,Builder仅仅是把组件的生产过程化成一步步实行而已。

这样做有什么实际作用呢?

在Java实际使用中,我们经经常使用到"池"(Pool)的概念,当资源提供者无法提供足够的资源,而且这些资源须要被非常多用户重复共享时,就须要使用池。"池"实际是一段内存,当池中有一些复杂的资源的"断肢"(比方数据库的连接池,或许有时一个连接会中断),假设循环再利用这些"断肢",将提高内存使用效率,提高池的性能,而在这里AlertDialog.builder就是这个池,改动Builder模式中p.apply(组装)类使之能诊断"断肢"断在哪个部件上,再修复这个部件.

Android开发之Buidler模式初探结合AlertDialog.Builder解说的更多相关文章

  1. Android开发之MVP模式的使用

    前几天发现,在Android项目代码里有一个Activity类行数居然有1000多行,而600行左右都是逻辑控制,真正和页面控件处理相关的代码不多,虽然可以用#region <>...#e ...

  2. Android开发之Java集合类性能分析

    对于Android开发者来说深入了解Java的集合类很有必要主要是从Collection和Map接口衍生出来的,目前主要提供了List.Set和 Map这三大类的集合,今天Android吧(ard8. ...

  3. Android开发之ViewPager+ActionBar+Fragment实现响应式可滑动Tab

     今天我们要实现的这个效果呢,在Android的应用中十分地常见,我们可以看到下面两张图,无论是系统内置的联系人应用,还是AnyView的阅读器应用,我们总能找到这样的影子,当我们滑动屏幕时,Tab可 ...

  4. Android开发之Java必备基础

    Android开发之Java必备基础 Java类型系统 Java语言基础数据类型有两种:对象和基本类型(Primitives).Java通过强制使用静态类型来确保类型安全,要求每个变量在使用之前必须先 ...

  5. Android开发之PopupWindow

      /* *  Android开发之PopupWindow * *  Created on: 2011-8-8 *  Author: blueeagle *  Email: liujiaxiang@g ...

  6. Android 开发之旅:深入分析布局文件&又是“Hello World!”

    http://www.cnblogs.com/skynet/archive/2010/05/20/1740277.html 引言 上篇可以说是一个分水岭,它标志着我们从Android应用程序理论进入实 ...

  7. android开发之Intent.setFlags()_让Android点击通知栏信息后返回正在运行的程序

    android开发之Intent.setFlags()_让Android点击通知栏信息后返回正在运行的程序     在应用里使用了后台服务,并且在通知栏推送了消息,希望点击这个消息回到activity ...

  8. Android开发之旅2:HelloWorld项目的目录结构

    引言 前面Android开发之旅:环境搭建及HelloWorld,我们介绍了如何搭建Android开发环境及简单地建立一个HelloWorld项目,本篇将通过HelloWorld项目来介绍Androi ...

  9. Android开发之MdiaPlayer详解

    Android开发之MdiaPlayer详解 MediaPlayer类可用于控制音频/视频文件或流的播放,我曾在<Android开发之基于Service的音乐播放器>一文中介绍过它的使用. ...

随机推荐

  1. Substrings 第37届ACM/ICPC 杭州赛区现场赛C题(hdu 4455)

    http://acm.hdu.edu.cn/showproblem.php?pid=4455 https://icpcarchive.ecs.baylor.edu/index.php?option=c ...

  2. qt button以及label实现不规则图形(五种方法:使用QSS,设置Mask图片,自己画)

    1.方法1:准备一张边界是透明的不规则图形 QPushButton * pbtn = new QPushButton;    pbtn->setStyleSheet("QPushBut ...

  3. 使用PageHeap.EXE或GFlags.EXE检查内存越界错误

    必先利其器之一:使用PageHeap.EXE或GFlags.EXE检查内存越界错误 Article last modified on 2002-6-3 ------------------------ ...

  4. 简单的Ajax应用实例

    从网页前端输入提示范围内的字符,然后显示从后台返回的结果 <html> <head> <meta http-equiv="content-type" ...

  5. UVALive 5791 Candy's Candy 解题报告

    比赛总结 题目 题意: 有f种口味的糖果,现在要把每颗糖果分到一些packs里面去.packs分两种: flavored pack:只有一种口味. variety pack:每种口味都有. 求满足下列 ...

  6. BZOJ 1367([Baltic2004]sequence-左偏树+中位数贪心)

    1367: [Baltic2004]sequence Time Limit: 20 Sec   Memory Limit: 64 MB Submit: 521   Solved: 159 [ Subm ...

  7. 定义自己的布局RelativeLayout 绘制网格线

    在Android画线必须由一个载体,无论是控制,无论是布局.实际上它们是从继承View.由画线的方式自己的控制或布局的定义是最常见的. 以下是在其定义中的小样本实现RelativeLayout绘制网络 ...

  8. HDU 1226 超级密码 (搜素)

    题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=1226 题意简单,本来是一道很简单的搜素题目. 但是有两个bug: 1.M个整数可能有重复的. 2.N可 ...

  9. java -D參数简化增加多个jar【简化设置classpath】

    1.-D<name>=<value> set a system property  设置系统属性. java命令引入jar时能够-cp參数,但时-cp不能用通配符(多个jar时 ...

  10. 祖国版Solowheel!IPS103 独轮思维车 - 三个月体验报告

    http://tieba.baidu.com/f?kz=2308652773&mo_device=1