温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

Android面试Intent采用的设计模式是什么

发布时间:2023-03-07 14:52:04 来源:亿速云 阅读:120 作者:iii 栏目:开发技术

这篇文章主要介绍了Android面试Intent采用的设计模式是什么的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇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采用的设计模式是什么”知识都有一定的了解,大家如果还想学习更多知识,欢迎关注亿速云行业资讯频道。

    向AI问一下细节

    免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

    AI