Android面试Intent采用了什么设计模式解析
目录
- 正文
- Intent 的关键源码
- 无视启动 flag、bundle 等数据
- 中拷贝策略是 COPY_MODE_HISTORY
- android 源码中还有很多地方采用了原型模式
正文
答案是采用了原型模式
原型模式的好处在于方便地拷贝某个实例的属性进行使用、又不会对原实例编程造成影响,其逻辑在于对 Cloneable
接口的实现。
Intent 的关键源码
// frameworks/base/core/Java/android/content/Intent.java public class Intent implements Parcelable, Cloneable { ... private static final int COPY_MODE_ALL = 0; private static final int COPY_MODE_FILTER = 1; private static final int COPY_MODE_HISTORY = 2; @Override public Object clone() { return new Intent(this); } public Intent(Intent o) { this(o, COPY_MODE_ALL); XkweggNzj } private Intenwww.devze.comt(Intent o, @CopyMode int copyMode) { this.MACtion = o.mAction; this.mData = o.mData; this.mType = o.mType; this.mIdentifier = o.mIdentifier; this.mPackage = o.mPackage; this.mComponent = o.mComponent; this.mOriginalIntent = o.mOriginalInjstent; ... if (copyMode != COPY_MODE_FILTER) { ... if (copyMode != COPY_MODE_HISTORY) { ... } } } ... }
可以看到 Intent
实现的 clone()
逻辑是直接调用了 new 并传入了自身实例,而非调用 super.clone() 进行拷贝。
默认的拷贝策略是 COPY_MODE_ALL
,顾名思义,将完整拷贝源实例的所有属性进行构造。其他的拷贝策略是 COPY_MODE_FILTER
指的是只拷贝跟 Intent-filter 相关的属性,即用来判断启动目标组件的 action、data、type、component、category 等必备信息。
无视启动 flag、bundle 等数据
// frameworks/base/core/java/android/content/Intent.java public class Intent implements Parcelable, Cloneable { ... public @NonNull Intent cloneFilter() { return new Intent(this, COPY_MODE_FILTER); } private Intent(Intent o, @CopyMode int copyMode) { this.mAction = o.mAction; ... if (copyMode != COPY_MODE_FILTER) { this.mFlags = o.mFlags; this.mContentUserHint = o.mContentUserHint; this.mLaunchToken = o.mLaunchToken; ... } } }
中拷贝策略是 COPY_MODE_HISTORY
不需要 bundle 等历史数据,保留 action 等基本信息和启动 flag 等数据。
// frameworks/base/core/java/android/content/Intent.java public class Intent implements Parcelable, Cloneable { ... public Intent maybeStripForHistory() { if (!canStripForHistory()) { return this; } return new Intent(this, COPY_MODE_HISTORY); } private Intent(Intent o, @CopyMode int copyMode) { this.mAction = o.mAction; ... if (copyMode != COPY_MODE_FILTER) { ... if (copyMode != COPY_MODE_HISTORY) { if (o.mExtras != null) { this.mExtras = new Bundle(o.mExtras); } if (o.mClipData != null) { this.mClipData = new ClipData(o.mClipData); } } else { if (o.mExtras != null && !o.mExtras.isDefinitelyEmpty()) { http://www.devze.com this.mExtras = Bundle.STRIPPED; } } } } }
总结起来:
Copy Mode | action 等数据 | flags 等数据 | bundle 等历史 |
---|---|---|---|
COPY_MODE_ALL | YES | YES | YES |
COPY_MODE_FILTER | YES | NO | NO |
COPY_MODE_HISTORY | YES | YES | NO |
Android 源码中还有很多地方采用了原型模式
除了 Intent
,Android 源码中还有很多地方采用了原型模式。
Bundle
也实现了 clone(),提供了 new Bundle(this) 的处理:
public final class Bundle extends BaseBundle implements Cloneable, Parcelable { ... @Override public Object clone() { return new Bundle(this); } }
组件信息类开发者_JS教程 ComponentName
也在 clone() 中提供了类似的实现:
public final class ComponentName implements Parcelable, Cloneable, Comparable<ComponentName> { ... public ComponentName clone() { return new ComponentName(mPackage, mClass); } }
工具类 IntArray
亦是如此:
public class IntArray implements Cloneable { ... @Override public IntArray clone() { return new IntArray(mValues.clone(), mSize); } }
原型模式也不一定非得实现 Cloneable,提供了类似的实现即可。比如:
Bitmap
没有实现该接口但提供了 copy()
,内部将传递原始 Bitmap 在 native 中的对象指针并伴随目标配置进行新实例的创建:
public final class ComponentName implements Parcelable, Cloneable, Comparable<ComponentName> { ... public Bitmap copy(Config config, boolean isMutable) { ... noteHardwareBitmapSlowCall(); Bitmap b = nativeCopy(mNativePtr, config.nativeInt, isMutable); if (b != null) { b.setPremultiplied(mRequestPremultiplied); b.mDensity = mDensity; } return b; } }
以上就是Android面试Intent采用了什么设计模式解析的详细内容,更多关于Android面试Intent设计模式的资料请关注我们其它相关文章!
精彩评论