Android开发之Buidler模式初探结合AlertDialog.Builder讲解

      什么是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讲解,布布扣,bubuko.com

Android开发之Buidler模式初探结合AlertDialog.Builder讲解

上一篇:nagios插件性能数据格式


下一篇:(转)浅谈移动操作系统的跨应用通信机制