Android面試Intent采用了什么設(shè)計(jì)模式解析
正文
答案是采用了原型模式
原型模式的好處在于方便地拷貝某個(gè)實(shí)例的屬性進(jìn)行使用、又不會(huì)對(duì)原實(shí)例造成影響,其邏輯在于對(duì) Cloneable 接口的實(shí)現(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 實(shí)現(xiàn)的 clone() 邏輯是直接調(diào)用了 new 并傳入了自身實(shí)例,而非調(diào)用 super.clone() 進(jìn)行拷貝。
默認(rèn)的拷貝策略是 COPY_MODE_ALL,顧名思義,將完整拷貝源實(shí)例的所有屬性進(jìn)行構(gòu)造。其他的拷貝策略是 COPY_MODE_FILTER 指的是只拷貝跟 Intent-filter 相關(guān)的屬性,即用來(lái)判斷啟動(dòng)目標(biāo)組件的 action、data、type、component、category 等必備信息。
無(wú)視啟動(dòng) 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 等基本信息和啟動(dòng) 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é)起來(lái):
| 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 也實(shí)現(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() 中提供了類似的實(shí)現(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);
}
}
原型模式也不一定非得實(shí)現(xiàn) Cloneable,提供了類似的實(shí)現(xiàn)即可。比如:
Bitmap 沒(méi)有實(shí)現(xiàn)該接口但提供了 copy(),內(nèi)部將傳遞原始 Bitmap 在 native 中的對(duì)象指針并伴隨目標(biāo)配置進(jìn)行新實(shí)例的創(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è)計(jì)模式解析的詳細(xì)內(nèi)容,更多關(guān)于Android面試Intent設(shè)計(jì)模式的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Android定時(shí)器和Handler用法實(shí)例分析
這篇文章主要介紹了Android定時(shí)器和Handler用法,實(shí)例分析了Android中的定時(shí)器與Handler相關(guān)使用技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2015-04-04
flutter InkWell實(shí)現(xiàn)水波紋點(diǎn)擊效果
這篇文章主要為大家詳細(xì)介紹了flutter InkWell實(shí)現(xiàn)水波紋點(diǎn)擊效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-07-07
Android UI組件LinearLayout線性布局詳解
這篇文章主要為大家詳細(xì)介紹了AndroidUI組件LinearLayout線性布局,具有一定的實(shí)用性,感興趣的小伙伴們可以參考一下2016-08-08
Android使用Rotate3dAnimation實(shí)現(xiàn)3D旋轉(zhuǎn)動(dòng)畫效果的實(shí)例代碼
利用Android的ApiDemos的Rotate3dAnimation實(shí)現(xiàn)了個(gè)圖片3D旋轉(zhuǎn)的動(dòng)畫,圍繞Y軸進(jìn)行旋轉(zhuǎn),還可以實(shí)現(xiàn)Z軸的縮放。點(diǎn)擊開始按鈕開始旋轉(zhuǎn),點(diǎn)擊結(jié)束按鈕停止旋轉(zhuǎn)。2018-05-05
關(guān)注Ionic底部導(dǎo)航按鈕tabs在android情況下浮在上面的處理
Ionic是一款流行的移動(dòng)端開發(fā)框架,但是剛?cè)腴T的同學(xué)會(huì)發(fā)現(xiàn),Ionic在iOS和Android的底部tabs顯示不一樣。在安卓情況下底部tabs會(huì)浮上去,下面給大家介紹下實(shí)現(xiàn)代碼,一起看看吧2016-12-12
Android中將一個(gè)圖片切割成多個(gè)圖片的實(shí)現(xiàn)方法
有種場(chǎng)景,我們想將一個(gè)圖片切割成多個(gè)圖片。比如我們?cè)陂_發(fā)一個(gè)拼圖的游戲,就首先要對(duì)圖片進(jìn)行切割2013-05-05
Android7.0行為變更之適配File Provider的方法
這篇文章主要介紹了Android7.0行為變更之適配File Provider的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-04-04
Android Handle原理(Looper,Handler和Message)三者關(guān)系案例詳解
這篇文章主要介紹了Android Handle原理(Looper,Handler和Message三者關(guān)系案例詳解,本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-08-08

