androidserializable
『壹』 android intnet 為什麼要serializable
Intent不僅能傳遞java基本數據類型,還能傳遞類的對象,前提是這些類必須實現Serializable或者Parcelable介面。
實現Serializable介面的方式是通過對象的序列化和反序列化來實現對象傳遞的。
實現Parcelable介面的方式是通過writeToParcel將你的對象映射成
Parcel對象,再通過createFromParcel將Parcel對象映射成你的對象。也可以將Parcel看成是一個流,通過
writeToParcel把對象寫到流裡面,在通過createFromParcel從流里讀取對象,只不過這個過程需要你來實現,因此寫的順序和讀的
順序必須一致。
1、實現Serializable介面
Serializable的作用是將數據對象存入位元組流當中,在需要時重新生成對象,主要應用是利用外部存儲設備保存對象狀態,以及通過網路傳輸對象等。
implements Serializable介面的的作用就是給對象打了一個標記,系統會自動將其序列化。
案例1:
1)User.java (implements Serializable )
2)MainActivity.java
User user = new User();
Intent intent = new Intent(this,Second.class);
intent.putExtra("user",user);
3)Second.java
Intent intent = getIntent();
User user = intent.getSerializableExtra("user");
2、實現Parcelable介面
1)為什麼要實現Parcelable介面來實現在Intent中傳遞對象?
a、在使用內存的時候,Parcelable比Serializable性能高,所以推薦使用Parcelable類。
b、Serializable在序列化的時候會產生大量的臨時變數,從而引起頻繁的GC。
注意:Parcelable不能使用在將數據存儲在磁碟上的情況,因為Parcelable不能很好的保存數據的持續性在外界有變化的情況下。因此在這種情況下,建議使用Serializable
2) Android中的新的序列化機制
在Android系統中,針對內存受限的移動設備,因此對性能要求更高,Android系統採用了新的IPC(進程間通信)機制,要求使用性能更出色的對象傳輸方式。因此Parcel類被設計出來,其定位就是輕量級的高效的對象序列化和反序列化機制。
Parcel的序列化和反序列化的讀寫全是在內存中進行,所以效率比JAVA序列化中使用外部存儲器會高很多。
Parcel類
就應用程序而言,在常使用Parcel類的場景就是在Activity間傳遞數據。在Activity間使用Intent傳遞數據的時候,可以通過Parcelable機制傳遞復雜的對象。
Parcel機制:本質上把它當成一個Serialize就可以了。只是Parcel的對象實在內存中完成的序列化和反序列化,利用的是連續的內存空間,因此更加高效。
案例:
步驟1:自定義實體類,實現Parcelable介面,重寫其兩個方法。
步驟2:該實體類必須添加一個常量CREATOR(名字大小寫都不能使其他的),該常量必須實現Parcelable的內部介面:Parcelable.Creator,並實現該介面中的兩個方法。
package com.example.intent_object;
import android.os.Parcel;
import android.os.Parcelable;
public class User implements Parcelable {
public String name;
public int age;
// 必須要創建一個名叫CREATOR的常量。
public static final Parcelable.Creator CREATOR = new Parcelable.Creator()
{
@Override
public User createFromParcel(Parcel source) {
return new User(source);
}
//重寫createFromParcel方法,創建並返回一個獲得了數據的user對象
@Override
public User[] newArray(int size) {
return new User[size];
}
};
@Override
public String toString() {
return name + ":" + age;
}
// 無參數構造器方法,供外界創建類的實例時調用
public User() {
}
// 帶參構造器方法私用化,本構造器僅供類的方法createFromParcel調用
private User(Parcel source) {
name = source.readString();
age = source.readInt();
}
@Override
public int describeContents() {
return 0;
}
// 將對象中的屬性保存至目標對象dest中
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name);
dest.writeInt(age);
}
//省略getter/setter
}
『貳』 android intent 傳入序列化serializable 必須實現get和set方法嗎
今天要給大家講一下Android中Intent中如何傳遞對象,就我目前所知道的有兩種方法,一種是Bundle.putSerializable(Key,Object);另一種是Bundle.putParcelable(Key,
Object);當然這些Object是有一定的條件的,前者是實現了Serializable介面,而後者是實現了Parcelable介面,為了讓大家更容易理解我還是照常寫了一個簡單的Demo,大家就一步一步跟我來吧!
第一步:新建一個Android工程命名為ObjectTranDemo(類比較多哦!)目錄結構如下圖:
第二步:修改main.xml布局文件(這里我增加了兩個按鈕)代碼如下
[plain] view plain
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Welcome to Mr wei's blog."
/>
<Button
android:id="@+id/button1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Serializable"
/>
<Button
android:id="@+id/button2"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Parcelable"
/>
</LinearLayout>
第三步:新建兩個類一個是Person.java實現Serializable介面,另一個Book.java實現Parcelable介面,代碼分別如下:
Person.java:
[java] view plain
package com.tutor.objecttran;
import java.io.Serializable;
public class Person implements Serializable {
private static final long serialVersionUID = -7060210544600464481L;
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
『叄』 android 怎樣把string類型的 serializable 反序列化
string類型本身就支持序列化的,不需要特殊處理
『肆』 Android兩種序列化的區別和作用
對於Serializable,類只需要實現Serializable介面,並提供一個序列化版本id(serialVersionUID)即可。而Parcelable則需要實現writeToParcel、describeContents函數以及靜態的CREATOR變數,實際上就是將如何打包和解包的工作自己來定義,而序列化的這些操作完全由底層實現。
『伍』 Android Parcelable和Serializable的區別
Parcelable和Serializable的作用、效率、區別及選擇:
1、作用Serializable的作用是為了保存對象的屬性到本地文件、資料庫、網路流、rmi以方便數據傳輸,當然這種傳輸可以是程序內的也可以是兩個程序間的。而Android的Parcelable的設計初衷是因為Serializable效率過慢,為了在程序內不同組件間以及不同Android程序間(AIDL)高效的傳輸數據而設計,這些數據僅在內存中存在,Parcelable是通過IBinder通信的消息的載體。從上面的設計上我們就可以看出優劣了。
2、效率及選擇Parcelable的性能比Serializable好,在內存開銷方面較小,所以在內存間數據傳輸時推薦使用Parcelable,如activity間傳輸數據,而Serializable可將數據持久化方便保存,所以在需要保存或網路傳輸數據時選擇Serializable,因為android不同版本Parcelable可能不同,所以不推薦使用Parcelable進行數據持久化。
3、編程實現對於Serializable,類只需要實現Serializable介面,並提供一個序列化版本id(serialVersionUID)即可。而Parcelable則需要實現writeToParcel、describeContents函數以及靜態的CREATOR變數,實際上就是將如何打包和解包的工作自己來定義,而序列化的這些操作完全由底層實現。
Parcelable的一個實現例子如下
[java] view plain
public class MyParcelable implements Parcelable {
private int mData;
private String mStr;
public int describeContents() {
return 0;
}
// 寫數據進行保存
public void writeToParcel(Parcel out, int flags) {
out.writeInt(mData);
out.writeString(mStr);
}
// 用來創建自定義的Parcelable的對象
public static final Parcelable.Creator CREATOR
= new Parcelable.Creator() {
public MyParcelable createFromParcel(Parcel in) {
return new MyParcelable(in);
}
public MyParcelable[] newArray(int size) {
return new MyParcelable[size];
}
};
// 讀數據進行恢復
private MyParcelable(Parcel in) {
mData = in.readInt();
mStr = in.readString();
}
}
從上面我們可以看出Parcel的寫入和讀出順序是一致的。如果元素是list讀出時需要先new一個ArrayList傳入,否則會報空指針異常。如下:
list = new ArrayList();
in.readStringList(list);
PS:
在自己使用時,read數據時誤將前面int數據當作long讀出,結果後面的順序錯亂,報如下異常,當類欄位較多時務必保持寫入和讀取的類型及順序一致。
11-21 20:14:10.317: E/AndroidRuntime(21114): Caused by:
java.lang.RuntimeException: Parcel android.os.Parcel@4126ed60: Unmarshalling
unknown type code 3014773 at offset 164
4、高級功能上Serializable序列化不保存靜態變數,可以使用Transient關鍵字對部分欄位不進行序列化,也可以覆蓋writeObject、readObject方法以實現序列化過程自定義。
『陸』 安卓傳值中使用Serializable和Parcelable的區別
在安卓開發中,我們經常會遇到這樣一個問題,就是要在兩個Activity之間傳遞一個實體對象,那麼我們就會用到
Serializable或者Parcelable,這兩個方法是用來序列化數據的,主要是用在不同的Activity之間在通過intent進行通信的
時候,數據傳輸時,Data部分的傳輸。
我們一般的在兩個Activity之間傳遞參數是這樣的,如下:
Intent it=new Intent();
Bundle bd=new Bundle();
bd.putInt("aa",20);
bd.putString("bb",ok);
it.setExtras(bd);
it.setClass(Activity1.this.class,Activity2.this.class) startActivity(it,Activity2.this.class);
就這樣傳遞,然後在第二個Activity中接收,如下:
Bundle bd1=(Bundle)getIntent().getExtras();
String str=bd1.getString("bb");
int ii=bd1.getInt("aa");
這樣,就得到了傳遞的數據,如果只是傳遞一些普通的數據,這個方法就可以了,但是如果傳輸的是一個自定義的結構(例如 自定義的類),或是嵌套(結構) 數據,就要進行序列化了,否則就會亂碼無法解析了。比如說,自定義一個類:
public Book {
private string bookname;
private string author;
Book(string s1,string s2){bookname=s1;author=s2}
public Setbookname(string s){bookname=s;}
public Setauthor(string s){author=s;}
public string getbookname(){return bookname ; }
public string getauthor(){return author;}
}
如果要傳遞這個類,那麼就要用到Serializable或者Parcelable了。
序列化原因:
1.永久性保存對象,保存對象的位元組序列到本地文件中;
2.通過序列化對象在網路中傳遞對象;
3.通過序列化在進程間傳遞對象。
但是Serializable與Parcelable兩個都是序列化,什麼時候用哪個呢?
1.在使用內存的時候,Parcelable 類比Serializable性能高,所以推薦使用Parcelable類。
2.Serializable在序列化的時候會產生大量的臨時變數,從而引起頻繁的GC。
3.Parcelable不能使用在要將數據存儲在磁碟上的情況,因為Parcelable不能很好的保證數據的持續性在外界有變化的情況下。盡管Serializable效率低點, 也不提倡用,但在這種情況下,還是建議你用Serializable 。
實現的時候
1.Serializable 的實現,只需要繼承 implements Serializable 即可。這只是給對象打了一個標記,系統會自動將其序列化。
比如說,像下面這樣:
public class Person implements Serializable {
private static final long serialVersionUID = -7060210544600464481L;
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
2.Parcelabel 的實現,需要在類中添加一個靜態成員變數 CREATOR,這個變數需要繼承 Parcelable.Creator 介面。
public class Book implements Parcelable {
private String bookName;
private String author;
private int publishTime;
public String getBookName() {
return bookName;
}
public void setBookName(String bookName) {
this.bookName = bookName;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public int getPublishTime() {
return publishTime;
}
public void setPublishTime(int publishTime) {
this.publishTime = publishTime;
}
public static final Parcelable.Creator<Book> CREATOR = new Creator<Book>() {
public Book createFromParcel(Parcel source) {
Book myBook = new Book();
myBook.bookName = source.readString();
myBook.author = source.readString();
myBook.publishTime = source.readInt();
return myBook;
}
public Book[] newArray(int size) {
return new Book[size];
}
};
public int describeContents() {
return 0;
}
public void writeToParcel(Parcel parcel, int flags) {
parcel.writeString(bookName);
parcel.writeString(author);
parcel.writeInt(publishTime);
}
}
『柒』 android serializable 怎麼傳值
Serializable的作用是為了保存對象的屬性到本地文件、資料庫、網路流、rmi以方便數據傳輸,當然這種傳輸可以是程序內的也可以是兩個程序間的。而Android的Parcelable的設計初衷是因為Serializable效率過慢,為了在程序內不同組件間以及不同Android程序間(AIDL)高效的傳輸數據而設計,這些數據僅在內存中存在,Parcelable是通過IBinder通信的消息的載體。 Parcelable的性能比Serializable好,在內存開銷方面較小,所以在內存間數據傳輸時推薦使用Parcelable,如activity間傳輸數據,而Serializable可將數據持久化方便保存,所以在需要保存或網路傳輸數據時選擇Serializable,因為android不同版本Parcelable可能不同,所以不推薦使用Parcelable進行數據持久化 對於Serializable,類只需要實現Serializable介面,並提供一個序列化版本id(serialVersionUID)即可。而Parcelable則需要實現writeToParcel、describeContents函數以及靜態的CREATOR變數,實際上就是將如何打包和解包的工作自己來定義,而序列化的這些操作完全由底層實現。