什么是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. 让盘古分词支持最新的Lucene.Net 3.0.3

    原文:让盘古分词支持最新的Lucene.Net 3.0.3 好多年没升级过的Lucene.Net最近居然升级了,到了3.0.3后接口发生了很大变化,原来好多分词库都不能用了,所以上次我把MMSeg给修 ...

  2. OCA读书笔记(7) - 管理数据库存储结构

    7.Managing Database Storage Structures 逻辑结构 数据库的存储结构有物理结构和逻辑结构组成的 物理结构:物理上,oracle是由一些操作系统文件组成的 SQL&g ...

  3. script:查看历史sql执行信息

    script:查看历史sql执行信息 SELECT *     FROM (SELECT '1.v$sql'||'实例号:'||GV$SQL.inst_id source,               ...

  4. ZenCoding Syntax

    语法: 后代:> 缩写:nav>ul>li 兄弟:+ 缩写:div+p+bq 上级:^ 缩写:div+div>p>span+em^bq 缩写:div+div>p&g ...

  5. ACE的构建(VC++6.0环境)

    ACE的构建(VC++6.0环境)Windows下ACE的构建1. 将ACE-5.5.zip解压到所需的安装目录,此处以E:/为例,解压后形成ACE_wrappers文件夹,因此ACE将会存在于ACE ...

  6. 《转载》常用算法经典代码(C++版)

    转自:http://blog.renren.com/blog/311453043/736944237 一.快速排序 void qsort(int x,int y) //待排序的数据存放在a[1]..a ...

  7. ASP.NET常被忽视的一些细节

    原文:ASP.NET常被忽视的一些细节 前段时间碰到一个问题:为什么在ASP.NET程序中定时器有时候会不工作? 这个问题看起来很奇怪,代码好像也没错,但就是结果与预期不一致. 其实这里是ASP.NE ...

  8. 在bmp上添加字符

    //打开位图文件,得到位图句柄   HBITMAP OpenBmpFile(HDC hDC, LPSTR lpszFileName)   {       HBITMAP hBmp = NULL;    ...

  9. [Word使用笔记]分类简介

    什么Vistual Studio , Eclipse , Xcode , 都弱爆了,Word比他们难多了 - -! 此分类用于记录Word的一些使用

  10. select下拉菜单反显不可改动,且submit能够提交数据

    首先通过后台funcA()将下拉菜单反显不可改动的数据response到disable.jsp页面,disable.jsp: <script> var data1=${result.obj ...