2016-02-13 138 views
1

在Android中實現Parcelable接口的正確方法是什麼?根據文檔,您應該實施writeToParcel方法並有一個CREATORParcelable實現的正確方法

public void writeToParcel(Parcel out, int flags) { 
    out.writeInt(mData); 
} 

但是,當我實現它無需增加CREATOR和離開writeToParcel()空的應用程序似乎仍正常工作。有時我會得到一個Bad Parcelable Exception,但我無法制定複製步驟。

這是我用它來傳遞一個對象從活動片段

Bundle bundle = new Bundle(); 
bundle.putParcelable(PageFragment.PAGE_FILTER_KEY, page); 
fragment.setArguments(bundle); 

那麼,什麼是添加的東西一樣out.writeInt(mData);可以預期什麼樣的問題的目的,如果不這樣做?

回答

4

可執行的實現主要有兩個過程步驟。

1將您的java對象寫入包含兩種方法的包裹

@Override 
    public int describeContents() { 
     return 0; 
    } 

    @Override 
    public void writeToParcel(Parcel dest, int flags) { 
     dest.writeString(cityName); 
     dest.writeString(macroName); 
     dest.writeString(id); 
    } 

其中描述的內容是爲您的內容設置標誌。大部分時間你只需要它不變。

public void writeToParcel(Parcel dest,int flags),您需要根據JAVA類中的字段逐步將您的Java類對象編寫爲包。在上面的例子中,我的課有三個字符串。您可以在宗地中編寫幾乎所有類型的對象。你只需要選擇適當的一個。像writeString(),寫列表()或writeObject()等

2.第二部分是從包裹

閱讀Java對象的回報,這部分需要兩件事情爲好。首先是你的Java類的CREATOR如下

public static final Creator<City> CREATOR = new Creator<City>() { 
     @Override 
     public City createFromParcel(Parcel in) { 
      return new City(in); 
     } 

     @Override 
     public City[] newArray(int size) { 
      return new City[size]; 
     } 
    }; 

在上面的例子中,我的Java類是City。它從包裹中讀取城市對象。但它叫城市類的新市(中)的構造函數。所以現在我需要一個構造函數來接受參數中的parcel對象。讓我們創造這個..

protected City(Parcel in) { 
     cityName = in.readString(); 
     macroName = in.readString(); 
     id = in.readString(); 
    } 

現在我們做一個類完整的充分證明parcelable。有一點需要注意,我們需要在受保護的城市(包裹)中讀取相同順序的成員,我們將它們放入包裹中,即寫入到writeToParcel()方法中。

關於如何重現badParcelable exeption中簡單地讓android從parcelable創建java對象。爲此,您可以選擇從Android設備上的開發人員選項中銷燬活動,並將您的應用程序放在該活動的後臺中,以便Android終止您的應用程序進程ID。通過重新創建活動(onCreate + Bundle)來恢復您的應用程序,如果您未正確實施parcelable,則會發生該異常。

2

但是,當我實現它,而不添加CREATOR並將writeToParcel()留空應用程序仍然似乎正常工作。

CREATOR用於從Parcel中讀取數據並將其轉換回對象。

writeToParcel()將您的數據存入Parcel

如果您的Parcelable實際上未被放入Parcel或從Parcel重新構成,那麼將其關閉的唯一方法將正常工作。示例包括LocalBroadcastManager

添加像out.writeInt(mData)這樣的東西的目的是什麼?

這與將out.write()OutputStream這樣的東西添加到同一個目的:它將寫入輸出。你的問題類似於問:「嘿,如果我不把數據寫入我的文件,我會遇到什麼樣的問題?」。

+0

我在顯示如何使用parcelable的問題中添加了一個片段。你可以看看,也許這就是我使用它是錯的? –

+0

@AdrianHristov:最終,'Bundle'可以放入'Parcel'中,並通過進程邊界發貨。在這種情況下,我不確定何時。我們知道它發生了,就像Android在後臺中終止你的進程一樣,但是用戶在離開它後很快返回到你的應用程序(例如30秒),我們的狀態得到恢復,唯一可行的方法是如果我們的狀態處於核心操作系統進程(而不是剛剛終止的進程)。 – CommonsWare

相關問題