Android面試Intent采用了什么設(shè)計模式解析
正文
答案是采用了原型模式
原型模式的好處在于方便地拷貝某個實例的屬性進行使用、又不會對原實例造成影響,其邏輯在于對 Cloneable
接口的實現(xiàn)。
Intent 的關(guān)鍵源碼
// 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
實現(xiàn)的 clone()
邏輯是直接調(diào)用了 new 并傳入了自身實例,而非調(diào)用 super.clone() 進行拷貝。
默認的拷貝策略是 COPY_MODE_ALL
,顧名思義,將完整拷貝源實例的所有屬性進行構(gòu)造。其他的拷貝策略是 COPY_MODE_FILTER
指的是只拷貝跟 Intent-filter 相關(guān)的屬性,即用來判斷啟動目標組件的 action、data、type、component、category 等必備信息。
無視啟動 flag、bundle 等數(shù)據(jù)
// 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 等歷史數(shù)據(jù),保留 action 等基本信息和啟動 flag 等數(shù)據(jù)。
// 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; } } } } }
總結(jié)起來:
Copy Mode | action 等數(shù)據(jù) | flags 等數(shù)據(jù) | bundle 等歷史 |
---|---|---|---|
COPY_MODE_ALL | YES | YES | YES |
COPY_MODE_FILTER | YES | NO | NO |
COPY_MODE_HISTORY | YES | YES | NO |
Android 源碼中還有很多地方采用了原型模式
除了 Intent
,Android 源碼中還有很多地方采用了原型模式。
Bundle
也實現(xiàn)了 clone(),提供了 new Bundle(this) 的處理:
public final class Bundle extends BaseBundle implements Cloneable, Parcelable { ... @Override public Object clone() { return new Bundle(this); } }
組件信息類 ComponentName
也在 clone() 中提供了類似的實現(xiàn):
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); } }
原型模式也不一定非得實現(xiàn) Cloneable,提供了類似的實現(xiàn)即可。比如:
Bitmap
沒有實現(xiàn)該接口但提供了 copy()
,內(nèi)部將傳遞原始 Bitmap 在 native 中的對象指針并伴隨目標配置進行新實例的創(chuàng)建:
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采用了什么設(shè)計模式解析的詳細內(nèi)容,更多關(guān)于Android面試Intent設(shè)計模式的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Android開發(fā)之Kotlin委托的原理與使用詳解
我們常用的委托模式怎么使用?在?Java?語言中需要我們手動的實現(xiàn),而在?Kotlin?語言中直接通過關(guān)鍵字?by?就可以實現(xiàn)委托,下面我們就一起看看不同種類的委托使用以及在?Android?常見的一些場景中的使用2023-03-03Android車載多媒體開發(fā)MediaSession框架示例詳解
這篇文章主要為大家介紹了Android車載多媒體開發(fā)MediaSession框架示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-10-10Android ImageView Src 和Background 區(qū)別
這篇文章主要介紹了Android ImageView Src 和Background 區(qū)別的相關(guān)資料,需要的朋友可以參考下2016-09-09一款不錯的android6.0、7.0權(quán)限管理器推薦
下面小編就為大家分享一篇一款不錯的android6.0、7.0權(quán)限管理器推薦,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-01-01