1.Serializable接口
Serializable是Java提供的一个序列化接口,为对象提供标准的序列化和反序列化操作。
内部序列化对象的原理:
序列化过程:
val shape = Shape(2,"Rec")
val out = ObjectOutputStream(FileOutputStream("serializable.txt"))
out.writeObject(shape)
out.close()
反序列化过程:
val input = ObjectInputStream(FileInputStream("serializable.txt"))
val shape = input.readObject()
input.close()
案例:点击按钮跳转界面并传递一个Shape对象到界面2
- 实体类实现Serializable接口,并添加serialVersionUID字段(非必需)
data class Shape(var id:Int,var name:String) :Serializable{
companion object {
const val serialVersionUID = 56789L
}
}
- 创建Intent并设置extra
val intent = Intent(this,Main2Activity::class.java)
val shape = Shape(2,"Rec")
intent.putExtra("shape",shape)
startActivity(intent)
- 接收并打印
val shape = intent.extras.getSerializable("shape")
Log.e("wdl", shape.toString())
?:serialVersionUID字段用来辅助序列化和反序列化过程的,工作机制:序列化时把当前类serialVersionUID写入序列化文件中,当反序列化时系统会去监测文件中的serialVersionUID看是否一致,一致则能成功反序列化,反之即失败。
2.Parcelable接口
传统用法:
- 实体类实现Parcelable接口并重写相关方法
class User : Parcelable {
private var age: Int? = null
private var name: String? = null
private var book: Book? = null
constructor(age: Int?, name: String, book: Book) {
this.age = age
this.name = name
this.book = book
}
/**
* 从序列化后的对象中创建原始对象
* 因为Book是另一个可序列化对象
* 所以它的反序列化过程需要传递当前线程的上下文类加载器
*
* @param in Parcel
*/
private constructor(`in`: Parcel) {
age = `in`.readInt()
name = `in`.readString()
book = `in`.readParcelable(Thread.currentThread().contextClassLoader)
}
/**
* 返回当前对象的内容描述
*
* @return 1:含描述符
* 基本为0
*/
override fun describeContents(): Int {
return 0
}
/**
* 将当前对象写入序列化结构中
*
* @param dest Parcel
* @param flags 1:标识当前对象需要作为返回值返回不能立即释放资源
* 基本为0
*/
override fun writeToParcel(dest: Parcel, flags: Int) {
dest.writeInt(age!!)
dest.writeString(name)
dest.writeParcelable(book, 0)
}
/*
* 完成反序列化的过程
* */
companion object CREATOR : Parcelable.Creator<User> {
override fun createFromParcel(parcel: Parcel): User {
return User(parcel)
}
override fun newArray(size: Int): Array<User?> {
return arrayOfNulls(size)
}
}
override fun toString(): String {
return "User{" +
"age=" + age +
", name='" + name + '\''.toString() +
", book=" + book +
'}'.toString()
}
}
- 设置exra
val intent = Intent(this,Main2Activity::class.java)
val user = User(2,"wdl",Book())
intent.putExtra("user",user)
startActivity(intent)
- 取出值
val user = intent.extras.getParcelable<User>("user")
Log.e("wdl", user.toString())
Parcelable的方法说明:
方法 | 功能 |
---|---|
private constructor(in : Parcel) | 从序列化后的对象中创建原始对象 |
writeToParcel(dest: Parcel, flags: Int) | 将当前对象写入序列化结构中;flag=1,表示当前对象需要作为返回值返回,一般为0 |
describeContents() | 返回当前对象的内容描述,一般为0,不返回 |
createFromParcel(parcel: Parcel) | 从序列化后的对象中创建原始对象 |
newArray(size: Int) | 从创建指定长度的原始对象数组 |
3.实际中如何抉择?
- 将对象序列化后存储到设备中或者通过网络传输建议使用Serializable
- Intent中传递推荐使用Parcelable,主要用于内存序列化效率较高
4.Kotlin与Java中快速使用序列化
- Java中:
一.Android Studio中安装parcelable插件
File->Setting->搜索框输入plugins->输入parcelable->安装->重启
二.使用
package com.wdl.monitoringofforest;
import android.os.Parcel;
import android.os.Parcelable;
/**
* author: wdl
* time: 2018/10/15 16:41
* des: TODO
*/
public class User implements Parcelable {
private String userName;
private int age;
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(this.userName);
dest.writeInt(this.age);
}
public User() {
}
private User(Parcel in) {
this.userName = in.readString();
this.age = in.readInt();
}
public static final Parcelable.Creator<User> CREATOR = new Parcelable.Creator<User>() {
@Override
public User createFromParcel(Parcel source) {
return new User(source);
}
@Override
public User[] newArray(int size) {
return new User[size];
}
};
}
- Kotlin中:
一.Parcelize 是 Kotlin 在 1.1.4 中,新增加的功能。
如果你需要使用它,先要保证 Android Studio 对 Kotlin 的插件已经升级到 1.1.4 之上的版本。
二.使用 @Parcelize
类前加一行注解@Parcelize
import android.os.Parcelable
import kotlinx.android.parcel.Parcelize
import java.io.Serializable
@Parcelize
data class User constructor(var userName: String, var age: Int) : Serializable, Parcelable
?:@Parcelize 是一个实验室功能,所以还需要在 Gradle 中,增加 experimental 配置。
app下的build.gradle配置如下:
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
android {
compileSdkVersion 27
defaultConfig {
applicationId "com.wdl.ipctwo"
minSdkVersion 21
targetSdkVersion 27
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
androidExtensions{
experimental = true
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation"org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'com.android.support:appcompat-v7:27.1.1'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}
关键在于:
androidExtensions{
experimental = true
}