首页 > 代码库 > Android开发之Buidler模式初探结合AlertDialog.Builder解说

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解说