答案是采用了原型形式

原型形式的优点在于方便地复制某个实例的特点进行使用、又不会对原实例形成影响,其逻辑在于对 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 相关的特点,即用来判断发动方针组件的 actiondatatypecomponentcategory 等必备信息。无视发动 flagbundle 等数据。

// 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

除了 IntentAndroid 源码中还有很多地方采用了原型形式。

  • 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;
       }
    }