什么是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. POJ 1753 Flip Game(二进制枚举)

    题目地址链接:http://poj.org/problem?id=1753 题目大意: 有4*4的正方形,每个格子要么是黑色,要么是白色,当把一个格子的颜色改变(黑->白或者白->黑)时, ...

  2. 怎样从ext3升级到ext4?

    Ext4 文件系统提供了更佳的性能和可靠性,具有了更为丰富的功能,那么,怎样从ext3升级到ext4呢? 首先,我们须要保证系统支持ext4,一般来说,内核版本号在2.6.28及以上的版本号才支持ex ...

  3. c#2解决c#1中的问题之用泛型实现参数化类型

    为什么需要泛型 你手中还有c#1的代码吗?数一数其中的强制转换有多少,特别是那些大量使用集合的代码.几乎每次使用foreach都需要隐式的强制转换.使用那些为不同数据类型而设计的类型,就意味着强制转换 ...

  4. Java魔法堂:JVM的运行模式 (转)

    一.前言 JVM有Client和Server两种运行模式.不同的模式对应不同的应用场景,而JVM也会有相应的优化.本文将记录JVM模式的信息,以便日后查阅. 二.介绍 在$JAVA_HOME/jre/ ...

  5. mysql update 有无索引对比

    <pre name="code" class="html">mysql> desc ProductInfo; +--------------- ...

  6. C语言实现通用数据结构的高效设计

    近期在阅读一个开源的C++代码.里面用到了大量的STL里面的东西.或许是自己一直用C而非常少用C++来实现算法的原因.STL里面大量的模板令人心烦.一直对STL的效率表示怀疑,但在网上搜到这样一个帖子 ...

  7. [Cocos2d-x]Android的android.mk文件通用版本

    原文地址: http://blog.ready4go.com/blog/2013/10/12/update-android-dot-mk-with-local-src-files-and-local- ...

  8. 14.4.3.2 Configuring Multiple Buffer Pool Instances 配置多个buffer pool 实例:

    14.4.3.2 Configuring Multiple Buffer Pool Instances 配置多个buffer pool 实例: 对于系统 buffer pool 有多个G的范围, 把b ...

  9. Android中关于JNI 的学习(六)JNI中注冊方法的实现

    在前面的样例中,我们会发现,当在Java类中定义一个方法的时候,例如以下: public class ParamTransferTest { public static int testval = 1 ...

  10. 解决NGINX的WORDPRESS伪静态规则失效的问题

    解决NGINX的WORDPRESS伪静态规则失效的问题 前两天搬到了EMSVPS的PR线路上,用上了最新的WDCP2.0管理面板,支持多用户管理(我们几个合租的VPS,最需要这个功能了),感觉很不错, ...