<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                [TOC] Android中對于對象有兩種方式可以實現序列化,分別為實現Serializable接口和實現Parcelable接口。 # Serializable接口 使用Serializable接口實現序列化時,只要讓類實現Serializable接口并聲明一個serialVersionUID即可。 ```java public class Book implements Serializable { private static final long serialVersionUID = 5474576373476457684L; private String mName; private float mPrice; public String getName() { return mName; } public void setName(String name) { mName = name; } public float getPrice() { return mPrice; } public void setPrice(float price) { mPrice = price; } } ``` # Parcelable接口 Parcelable接口聲明如下: ```java public interface Parcelable { public @ContentsFlags int describeContents(); // 對象寫入Parcel public void writeToParcel(Parcel dest, @WriteFlags int flags); public interface Creator<T> { // 從Parcel中恢復對象 public T createFromParcel(Parcel source); // 創建一個對象數組 public T[] newArray(int size); } // 支持傳入ClassLoader public interface ClassLoaderCreator<T> extends Creator<T> { public T createFromParcel(Parcel source, ClassLoader loader); } } ``` 實現類示例如下: ```java public class Book implements Parcelable { private String mName; private String mAuthor; private float mPrice; protected Book(Parcel in) { mName = in.readString(); mAuthor = in.readString(); mPrice = in.readFloat(); } public static final Creator<Book> CREATOR = new Creator<Book>() { @Override public Book createFromParcel(Parcel in) { return new Book(in); } @Override public Book[] newArray(int size) { return new Book[size]; } }; @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel dest, int flags) { dest.writeString(mName); dest.writeString(mAuthor); dest.writeFloat(mPrice); } } ``` 需要注意的一點是,寫入對象到Parcel和從Parcel讀取對象兩個方法中,成員變量的順序需要一致,否則將會產生異常。 # 對比 在實際開發中,推薦使用Parcelable接口: 1、Serializable使用簡單但是開銷大,序列化和反序列化過程需要大量的IO操作,使用了反射機制,過程相對緩慢,且產生很多臨時對象需要頻繁垃圾回收 2、Parcelable使用稍微麻煩,但是效率高 3、Parcelable推薦用在內存序列化上;Serializable推薦用在將對象序列化到存儲設備中或對象序列化后通過網絡傳輸。 # Parcelable源碼分析 ## 序列化 我們使用Intent傳遞對象是最常見的使用Parcelable序列化使用場景,下面我們來看看序列化后的對象到底是怎么傳遞的。 ```java public @NonNull Intent putExtra(String name, Parcelable value) { if (mExtras == null) { mExtras = new Bundle(); } mExtras.putParcelable(name, value); return this; } ``` 上面是Intent的putExtra方法,我們在傳遞數據時將Parcelable序列化后的對象作為參數傳入。可以看到Parcelable對象被存放到mExtras,也就是一個Bundle對象中。看看Bundle的putParcelable方法: ```java ArrayMap<String, Object> mMap = null; public void putParcelable(@Nullable String key, @Nullable Parcelable value) { //... mMap.put(key, value); } ``` 可以看到,序列化后的對象被直接存到了Bundle的一個Map集合中了。由于Bundle也實現了Parcelable接口,在傳遞數據時,Bundle也是會被傳遞過去的,會調用其writeToParcel方法: ```java // 將Bundle中的內容寫入到Parcel對象中 public void writeToParcel(Parcel parcel, int flags) { //... super.writeToParcelInner(parcel, flags); } void writeToParcelInner(Parcel parcel, int flags) { //... // 此處直接將Bundle的整個mMap傳入 parcel.writeArrayMapInternal(map); } ``` 來看看Parcel對象拿到Map后的操作: ```java void writeArrayMapInternal(ArrayMap<String, Object> val) { //... // 將map中的每一個對象依次寫入Parcel中 for (int i=0; i<N; i++) { writeString(val.keyAt(i)); writeValue(val.valueAt(i)); } } public final void writeValue(Object v) { if (v instanceof String) { writeInt(VAL_STRING); writeString((String) v); } else if (v instanceof Integer) { writeInt(VAL_INTEGER); writeInt((Integer) v); } else if (v instanceof Parcelable) { writeInt(VAL_PARCELABLE); writeParcelable((Parcelable) v, 0); } //... } public final void writeParcelable(Parcelable p, int parcelableFlags) { //... writeParcelableCreator(p); //調用序列化后的Parcelable對象的writeToParcel方法 p.writeToParcel(this, parcelableFlags); } ``` 可以看到,最終調用了我們實現序列化對象的writeToParcel方法。 ## 反序列化 接下來看看從Parcel中恢復Bundle對象: ```java public void readFromParcel(Parcel parcel) { super.readFromParcelInner(parcel); mFlags = FLAG_ALLOW_FDS; maybePrefillHasFds(); } void readFromParcelInner(Parcel parcel) { int length = parcel.readInt(); readFromParcelInner(parcel, length); } ``` 接下來看看readFromParcelInner方法: ```java private void readFromParcelInner(Parcel parcel, int length) { //... Parcel p = Parcel.obtain(); p.setDataPosition(0); p.appendFrom(parcel, offset, length); p.adoptClassCookies(parcel); p.setDataPosition(0); mParcelledData = p; } ``` 可以看到,為mParcelledData進行賦值。然后這條線就斷了,那么我們就從Bundle中獲取傳遞過來的Parcelable對象看看: ```java public <T extends Parcelable> T getParcelable(@Nullable String key) { unparcel(); Object o = mMap.get(key); //... return (T) o; } ``` 首先調用unparcel方法,然后根據key從map中獲取Parcelable對象。來看看unparcel方法: ```java void unparcel() { final Parcel source = mParcelledData; if (source != null) { // 這個source就是我們前面拿到的Parcel對象 initializeFromParcelLocked(source, /*recycleParcel=*/ true); } //... } ``` 看看initializeFromParcelLocked方法: ```java private void initializeFromParcelLocked(@NonNull Parcel parcelledData, boolean recycleParcel) { ArrayMap<String, Object> map = mMap; //... try { parcelledData.readArrayMapInternal(map, count, mClassLoader); } catch (BadParcelableException e) { //... } finally { mMap = map; if (recycleParcel) { recycleParcel(parcelledData); } mParcelledData = null; } } ``` 最終調用了parcelledData的readArrayMapInternal方法: ```java void readArrayMapInternal(ArrayMap outVal, int N, ClassLoader loader) { int startPos; // 依次取出每一個屬性,并存入map while (N > 0) { String key = readString(); Object value = readValue(loader); outVal.append(key, value); N--; } outVal.validate(); } ``` 讀取屬性的readValue方法源碼如下: ```java public final Object readValue(ClassLoader loader) { int type = readInt(); switch (type) { case VAL_STRING: return readString(); case VAL_INTEGER: return readInt(); case VAL_PARCELABLE: return readParcelable(loader); //... } } public final <T extends Parcelable> T readParcelable(ClassLoader loader) { // 獲取Creator Parcelable.Creator<?> creator = readParcelableCreator(loader); //... return (T) creator.createFromParcel(this); } ``` 最終調用Creator的createFromParcel方法,也就是我們自己序列化對象寫的那個createFromParcel方法。其中獲取Creator代碼如下: ```java public final Parcelable.Creator<?> readParcelableCreator(ClassLoader loader) { String name = readString(); Parcelable.Creator<?> creator; synchronized (mCreators) { HashMap<String,Parcelable.Creator<?>> map = mCreators.get(loader); if (map == null) { map = new HashMap<>(); mCreators.put(loader, map); } creator = map.get(name); if (creator == null) { try { // If loader == null, explicitly emulate Class.forName(String) "caller // classloader" behavior. ClassLoader parcelableClassLoader = (loader == null ? getClass().getClassLoader() : loader); // Avoid initializing the Parcelable class until we know it implements // Parcelable and has the necessary CREATOR field. http://b/1171613. Class<?> parcelableClass = Class.forName(name, false /* initialize */, parcelableClassLoader); if (!Parcelable.class.isAssignableFrom(parcelableClass)) { throw new BadParcelableException("Parcelable protocol requires that the " + "class implements Parcelable"); } Field f = parcelableClass.getField("CREATOR"); if ((f.getModifiers() & Modifier.STATIC) == 0) { throw new BadParcelableException("Parcelable protocol requires " + "the CREATOR object to be static on class " + name); } Class<?> creatorType = f.getType(); if (!Parcelable.Creator.class.isAssignableFrom(creatorType)) { // Fail before calling Field.get(), not after, to avoid initializing // parcelableClass unnecessarily. throw new BadParcelableException("Parcelable protocol requires a " + "Parcelable.Creator object called " + "CREATOR on class " + name); } creator = (Parcelable.Creator<?>) f.get(null); } map.put(name, creator); } } return creator; } ``` 可以看到,通過反射拿到Creator。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看