Android 序列化对象

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

  1. 实体类实现Serializable接口,并添加serialVersionUID字段(非必需)
data class Shape(var id:Int,var name:String) :Serializable{
    companion object {
        const val serialVersionUID = 56789L
    }
}
  1. 创建Intent并设置extra
 val intent = Intent(this,Main2Activity::class.java)
 val shape = Shape(2,"Rec")
intent.putExtra("shape",shape)
startActivity(intent)
  1. 接收并打印
 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.实际中如何抉择?

  1. 将对象序列化后存储到设备中或者通过网络传输建议使用Serializable
  2. Intent中传递推荐使用Parcelable,主要用于内存序列化效率较高

4.Kotlin与Java中快速使用序列化

  1. 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];
        }
    };
}

  1. 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
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值