Android面试Intent采用了什么设计模式解析

 更新时间:2023年03月05日 09:47:18   作者:TechMerger  
这篇文章主要为大家介绍了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 Modeaction 等数据flags 等数据bundle 等历史
COPY_MODE_ALLYESYESYES
COPY_MODE_FILTERYESNONO
COPY_MODE_HISTORYYESYESNO

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开发之Kotlin委托的原理与使用详解

    Android开发之Kotlin委托的原理与使用详解

    我们常用的委托模式怎么使用?在 Java 语言中需要我们手动的实现,而在 Kotlin 语言中直接通过关键字 by 就可以实现委托,下面我们就一起看看不同种类的委托使用以及在 Android 常见的一些场景中的使用
    2023-03-03
  • Android自定义View实现拖动选择按钮

    Android自定义View实现拖动选择按钮

    这篇文章主要为大家详细介绍了Android自定义View实现拖动选择按钮的具体代码,感兴趣的小伙伴们可以参考一下
    2016-05-05
  • Android实现IOS相机滑动控件

    Android实现IOS相机滑动控件

    这篇文章主要为大家详细介绍了Android实现IOS相机滑动控件的相关资料,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-08-08
  • Android开发Retrofit源码分析

    Android开发Retrofit源码分析

    这篇文章主要为大家介绍了Android开发Retrofit源码分析详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-07-07
  • Android view绘制流程详解

    Android view绘制流程详解

    View 的绘制是在 ViewRoot 的 performTraversals() 开始的,它历经 measure(测量), layout(布局), draw(绘制) 三个流程将 View 显示在屏幕上。
    2021-05-05
  • android使用多线程更新ui示例分享

    android使用多线程更新ui示例分享

    在Android平台中多线程应用很广泛,在UI更新、游戏开发和耗时处理(网络通信等)等方面都需要多线程,下面是一个在线程中更新UI的代码
    2014-01-01
  • Android车载多媒体开发MediaSession框架示例详解

    Android车载多媒体开发MediaSession框架示例详解

    这篇文章主要为大家介绍了Android车载多媒体开发MediaSession框架示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-10-10
  • Android ImageView Src 和Background 区别

    Android ImageView Src 和Background 区别

    这篇文章主要介绍了Android ImageView Src 和Background 区别的相关资料,需要的朋友可以参考下
    2016-09-09
  • 一款不错的android6.0、7.0权限管理器推荐

    一款不错的android6.0、7.0权限管理器推荐

    下面小编就为大家分享一篇一款不错的android6.0、7.0权限管理器推荐,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-01-01
  • Android中使用Post请求的方法

    Android中使用Post请求的方法

    这篇文章主要介绍了Android中使用Post请求的方法,实例分析了Android中使用post请求的原理与具体实现技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-07-07

最新评论