2000字范文,分享全网优秀范文,学习好帮手!
2000字范文 > Android 最常用的设计模式五 安卓源码分析——建造者模式

Android 最常用的设计模式五 安卓源码分析——建造者模式

时间:2020-10-09 17:51:12

相关推荐

Android 最常用的设计模式五    安卓源码分析——建造者模式

我的理解:就是构造函数的时候,可以灵活的设置它的值,如果构造函数很多的值,不用全部传,需要什么值,就放什么值,封装了set方法一样,一步一步构造自己想要的属性

它的意思就是将一个对象和怎么构建这个对象分离开来,如果你想构建一个对象,你把这个消息告诉构建者,并且将自己对这个对象的各种要求告诉建造者,然后建造者根据这 些要求进行捣鼓,然后,你所需要的一个对象就出来了。

BUILDER—MM最爱听的就是“我爱你”这句话了,见到不同地方的MM,要能够用她们的方言跟她说这句话哦,我有一个多种语言翻译机,上面每种语言都有一个按键,见到MM我只要按对应的键,它就能够用相应的语言说出“我爱你”这句话了,国外的MM也可以轻松搞定,这就是我的“我爱你”builder。(这一定比美军在伊拉克用的翻译机好卖)

建造模式:将对象的内部表象和对象的生成过程分割开来,从而使一个建造过程生成具有不同的内部表象的产品对象。建造模式使得产品内部表象可以独立的变化,客户不必知道产品内部组成的细节。建造模式可以强制实行一种分步骤进行的建造过程。

建造者模式把构造和表示分离开,根据客户需求生产一个相应的对象。

本来呢,我们根据Builder接口实现不同的具体的ConcreteBuilder,就可生产不同的对象了。

但是,下面例子的只有一个Builder,所以也没有接口Builder,也没有其他的ConcreteBuilder。

但是我今天要讲的例子太简单,简单到都不觉得是建造者模式,但是又有建造者模式的感觉。

建造者模式:AlertDialog.Builder

简介:可以分步地构造每一部分。

AlertDialog里面有一个静态类builder,里面封装什么设置按钮的文字的

public static class Builder {private final AlertController.AlertParams P; /** * Creates a builder for an alert dialog that uses the default alert * dialog theme. *<p> * The default alert dialog theme is defined by * {@linkandroid.R.attr#alertDialogTheme} within the parent * {@codecontext}'s theme. * *@paramcontextthe parent context */ public Builder(Context context) {this(context, resolveDialogTheme(context, 0)); }

public class AlertDialog extends Dialog implements DialogInterface {private AlertController mAlert; /** * Hint layout to the side. *@hide*/ public static final intLAYOUT_HINT_SIDE= 1; /** * Creates an alert dialog that uses the default alert dialog theme. *<p> * The default alert dialog theme is defined by * {@linkandroid.R.attr#alertDialogTheme} within the parent * {@codecontext}'s theme. * *@paramcontextthe parent context *@seeandroid.R.styleable#Theme_alertDialogTheme */ protected AlertDialog(Context context) {this(context, 0); }/** * Creates an alert dialog that uses the default alert dialog theme and a * custom cancel listener. *<p> * This is functionally identical to: *<pre> *AlertDialog dialog = new AlertDialog(context); *alertDialog.setCancelable(cancelable); *alertDialog.setOnCancelListener(cancelListener); *</pre> *<p> * The default alert dialog theme is defined by * {@linkandroid.R.attr#alertDialogTheme} within the parent * {@codecontext}'s theme. * *@paramcontextthe parent context *@seeandroid.R.styleable#Theme_alertDialogTheme */ protected AlertDialog(Context context, boolean cancelable, OnCancelListener cancelListener) {this(context, 0); setCancelable(cancelable); setOnCancelListener(cancelListener); }/** * Gets the list view used in the dialog. * *@returnThe {@linkListView} from the dialog. */ public ListView getListView() {return mAlert.getListView(); }@Override public void setTitle(CharSequence title) {super.setTitle(title); mAlert.setTitle(title); }/** * Set resId to 0 if you don't want an icon. *@paramresIdthe resourceId of the drawable to use as the icon or 0 * if you don't want an icon. */ public void setIcon(@DrawableRes int resId) {mAlert.setIcon(resId); }public void setIcon(Drawable icon) {mAlert.setIcon(icon); }public static class Builder {private final AlertController.AlertParams P; /** * Creates a builder for an alert dialog that uses the default alert * dialog theme. *<p> * The default alert dialog theme is defined by * {@linkandroid.R.attr#alertDialogTheme} within the parent * {@codecontext}'s theme. * *@paramcontextthe parent context */public Builder(Context context) {this(context, resolveDialogTheme(context, 0)); }/** * Creates a builder for an alert dialog that uses an explicit theme * resource. *<p> * The specified theme resource ({@codethemeResId}) is applied on top * of the parent {@codecontext}'s theme. It may be specified as a * style resource containing a fully-populated theme, such as * {@linkandroid.R.style#Theme_Material_Dialog}, to replace all * attributes in the parent {@codecontext}'s theme including primary * and accent colors. *<p> * To preserve attributes such as primary and accent colors, the * {@codethemeResId} may instead be specified as an overlay theme such * as {@linkandroid.R.style#ThemeOverlay_Material_Dialog}. This will * override only the window attributes necessary to style the alert * window as a dialog. *<p> * Alternatively, the {@codethemeResId} may be specified as {@code0} * to use the parent {@codecontext}'s resolved value for * {@linkandroid.R.attr#alertDialogTheme}. * *@paramcontextthe parent context *@paramthemeResIdthe resource ID of the theme against which to inflate * this dialog, or {@code0} to use the parent * {@codecontext}'s default alert dialog theme */public Builder(Context context, int themeResId) {P = new AlertController.AlertParams(new ContextThemeWrapper(context, resolveDialogTheme(context, themeResId))); }/** * Returns a {@linkContext} with the appropriate theme for dialogs created by this Builder. * Applications should use this Context for obtaining LayoutInflaters for inflating views * that will be used in the resulting dialogs, as it will cause views to be inflated with * the correct theme. * *@returnA Context for built Dialogs. */public Context getContext() {return P.mContext; }/** * Set the title using the given resource id. * *@returnThis Builder object to allow for chaining of calls to set methods */public Builder setTitle(@StringRes int titleId) {P.mTitle = P.mContext.getText(titleId); return this; }

简单说就是把自个儿构造函数变成了保护类型,就不能主动创建了。那么创建需要一个使用它内部类Builder

ImageLoader的源码也用了构造者模式

public final class ImageLoaderUtil {// ImageLoader初始化 static {File cacheDir = StorageUtils.getOwnCacheDirectory(CXApplication.mAppContext, "imgCache"); FileNameGenerator fileNameGenerator = new Md5FileNameGenerator();// UnlimitedDiskCache diskCache = new UnlimitedDiskCache(cacheDir, null, fileNameGenerator); UsingFreqLimitedMemoryCache memoryCache = new UsingFreqLimitedMemoryCache((int) (Runtime.getRuntime().maxMemory() / 16));// 缓存内存大小 DisplayImageOptions displayImageOptions = new DisplayImageOptions.Builder().cacheOnDisk(true)/* 磁盘缓存 */.cacheInMemory(true) /* 内存缓存 */.imageScaleType(ImageScaleType.IN_SAMPLE_POWER_OF_2).bitmapConfig(Bitmap.Config.RGB_565).showImageOnLoading(R.drawable.j_iv_loading)// 加载过程图片.showImageOnFail(R.drawable.j_iv_loading_fail_large)// 失败图片.build(); ImageLoaderConfiguration imageLoaderConfiguration = new ImageLoaderConfiguration.Builder(CXApplication.mAppContext).diskCache(diskCache).memoryCache(memoryCache).defaultDisplayImageOptions(displayImageOptions).denyCacheImageMultipleSizesInMemory().threadPoolSize(4)// 线程池内加载的数量.tasksProcessingOrder(QueueProcessingType.FIFO)// 先进先出.memoryCacheExtraOptions(CXLocConfig.ScreenWidthPixels, CXLocConfig.ScreenHeightPixels)// 最大内存缓存图片宽高.diskCacheFileCount(100)// 磁盘最多缓存100张图片.diskCacheSize(50 * 1024 * 1024)// 磁盘最大缓存50M的图片.memoryCache(new WeakMemoryCache()).memoryCacheSizePercentage(15).build(); ImageLoader.getInstance().init(imageLoaderConfiguration);// 全局初始化此配置 }

public final class DisplayImageOptions {private final int imageResOnLoading; private final int imageResForEmptyUri; private final int imageResOnFail; private final Drawable imageOnLoading; private final Drawable imageForEmptyUri; private final Drawable imageOnFail; private final boolean resetViewBeforeLoading; private final boolean cacheInMemory; private final boolean cacheOnDisk; private final ImageScaleType imageScaleType; private final Options decodingOptions; private final int delayBeforeLoading; private final boolean considerExifParams; private final Object extraForDownloader; private final BitmapProcessor preProcessor; private final BitmapProcessor postProcessor; private final BitmapDisplayer displayer; private final Handler handler; private final boolean isSyncLoading; private DisplayImageOptions(DisplayImageOptions.Builder builder) {this.imageResOnLoading = builder.imageResOnLoading; this.imageResForEmptyUri = builder.imageResForEmptyUri; this.imageResOnFail = builder.imageResOnFail; this.imageOnLoading = builder.imageOnLoading; this.imageForEmptyUri = builder.imageForEmptyUri; this.imageOnFail = builder.imageOnFail; this.resetViewBeforeLoading = builder.resetViewBeforeLoading; this.cacheInMemory = builder.cacheInMemory; this.cacheOnDisk = builder.cacheOnDisk; this.imageScaleType = builder.imageScaleType; this.decodingOptions = builder.decodingOptions; this.delayBeforeLoading = builder.delayBeforeLoading; this.considerExifParams = builder.considerExifParams; this.extraForDownloader = builder.extraForDownloader; this.preProcessor = builder.preProcessor; this.postProcessor = builder.postProcessor; this.displayer = builder.displayer; this.handler = builder.handler; this.isSyncLoading = builder.isSyncLoading; }public boolean shouldShowImageOnLoading() {return this.imageOnLoading != null || this.imageResOnLoading != 0; }public boolean shouldShowImageForEmptyUri() {return this.imageForEmptyUri != null || this.imageResForEmptyUri != 0; }public boolean shouldShowImageOnFail() {return this.imageOnFail != null || this.imageResOnFail != 0; }boolean isSyncLoading() {return this.isSyncLoading; }public static DisplayImageOptions createSimple() {return (new DisplayImageOptions.Builder()).build(); }public static class Builder {

如Gson中的GsonBuilder,代码太长了,就不贴了,有兴趣自己去看源码,这里只贴出其Builder的使用方法。

GsonBuilder builder=new GsonBuilder();

Gson gson=builder.setPrettyPrinting()

.disableHtmlEscaping()

.generateNonExecutableJson()

.serializeNulls()

.create();

EventBus中也有一个Builder,只不过这个Builder外部访问不到而已,因为它的构造函数不是public的,但是你可以在EventBus这个类中看到他的应用

public static EventBusBuilder builder() {

return new EventBusBuilder();

}

public EventBus() {

this(DEFAULT_BUILDER);

}

EventBus(EventBusBuilder builder) {

subscriptionsByEventType = new HashMap<Class<?>, CopyOnWriteArrayList<Subscription>>();

typesBySubscriber = new HashMap<Object, List<Class<?>>>();

stickyEvents = new ConcurrentHashMap<Class<?>, Object>();

mainThreadPoster = new HandlerPoster(this, Looper.getMainLooper(), 10);

backgroundPoster = new BackgroundPoster(this);

asyncPoster = new AsyncPoster(this);

subscriberMethodFinder = new SubscriberMethodFinder(builder.skipMethodVerificationForClasses);

logSubscriberExceptions = builder.logSubscriberExceptions;

logNoSubscriberMessages = builder.logNoSubscriberMessages;

sendSubscriberExceptionEvent = builder.sendSubscriberExceptionEvent;

sendNoSubscriberEvent = builder.sendNoSubscriberEvent;

throwSubscriberException = builder.throwSubscriberException;

eventInheritance = builder.eventInheritance;

executorService = builder.executorService;

}

网络请求框架OkHttp

private Response(Builder builder) {

this.request = builder.request;

this.protocol = builder.protocol;

this.code = builder.code;

this.message = builder.message;

this.handshake = builder.handshake;

this.headers = builder.headers.build();

this.body = builder.body;

workResponse = workResponse;

this.cacheResponse = builder.cacheResponse;

this.priorResponse = builder.priorResponse;

}

参考博客:

/weiCloudS/blog/392872

/fofu33/article/details/50973172

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。