Android面试Intent采用了什么设计模式解析
正文
答案是采用了原型模式
原型模式的好处在于方便地拷贝某个实例的属性进行使用、又不会对原实例造成影响,其逻辑在于对 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);
}
private Intent(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.mOriginalIntent;
...
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()) {
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);
}
}
组件信息类 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设计模式的资料请关注脚本之家其它相关文章!
相关文章
Android UI组件LinearLayout线性布局详解
这篇文章主要为大家详细介绍了AndroidUI组件LinearLayout线性布局,具有一定的实用性,感兴趣的小伙伴们可以参考一下2016-08-08
Android使用Rotate3dAnimation实现3D旋转动画效果的实例代码
利用Android的ApiDemos的Rotate3dAnimation实现了个图片3D旋转的动画,围绕Y轴进行旋转,还可以实现Z轴的缩放。点击开始按钮开始旋转,点击结束按钮停止旋转。2018-05-05
关注Ionic底部导航按钮tabs在android情况下浮在上面的处理
Ionic是一款流行的移动端开发框架,但是刚入门的同学会发现,Ionic在iOS和Android的底部tabs显示不一样。在安卓情况下底部tabs会浮上去,下面给大家介绍下实现代码,一起看看吧2016-12-12
Android7.0行为变更之适配File Provider的方法
这篇文章主要介绍了Android7.0行为变更之适配File Provider的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧2018-04-04
Android Handle原理(Looper,Handler和Message)三者关系案例详解
这篇文章主要介绍了Android Handle原理(Looper,Handler和Message三者关系案例详解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下2021-08-08


最新评论