Skip to content

Instantly share code, notes, and snippets.

@mcxiaoke
Forked from juanchosaravia/KotlinParcelable
Created January 28, 2016 02:57
Show Gist options
  • Select an option

  • Save mcxiaoke/f6eb2eb8049d1cfc352a to your computer and use it in GitHub Desktop.

Select an option

Save mcxiaoke/f6eb2eb8049d1cfc352a to your computer and use it in GitHub Desktop.

Revisions

  1. @juanchosaravia juanchosaravia revised this gist Jan 22, 2016. 1 changed file with 43 additions and 113 deletions.
    156 changes: 43 additions & 113 deletions KotlinParcelable
    Original file line number Diff line number Diff line change
    @@ -1,3 +1,5 @@
    // ------------ Helper extension functions:

    // Inline function to create Parcel Creator
    inline fun <reified T : Parcelable> createParcel(crossinline createFromParcel: (Parcel) -> T?): Parcelable.Creator<T> =
    object : Parcelable.Creator<T> {
    @@ -9,137 +11,65 @@ inline fun <reified T : Parcelable> createParcel(crossinline createFromParcel: (
    fun <T : Parcelable> Parcel.readParcelable(creator: Parcelable.Creator<T>): T? {
    if (readString() != null) return creator.createFromParcel(this) else return null
    }

    // IMPORTANT NOTE:
    // data class: does not support empty primary constructors and doesn't allow the use of lateinit modifier in the constructor.
    // That's why I ended up using regular classes and generating the equal and hash method with Android Studio.
    // I don't really like the idea of not using data classes but I prefer to avoid doing null checks while trying to use this models.


    // EXAMPLE with custom classes

    class User() : Parcelable {

    companion object {
    val CREATOR = createParcel { User(it) }
    }

    lateinit var _id: String
    lateinit var email: String
    lateinit var name: Name
    lateinit var phone: String
    lateinit var additional: Additional

    protected constructor(parcelIn: Parcel) : this() {
    this._id = parcelIn.readString()
    this.email = parcelIn.readString()
    this.name = parcelIn.readParcelable(Name.CREATOR) ?: Name()
    this.phone = parcelIn.readString()
    this.additional = parcelIn.readParcelable(Additional.CREATOR) ?: Additional()
    }

    override fun describeContents(): Int {
    return 0
    }

    override fun writeToParcel(dest: Parcel, flags: Int) {
    dest.writeString(_id)
    dest.writeString(email)
    dest.writeParcelable(name, 0)
    dest.writeString(phone)
    dest.writeParcelable(additional, 0)
    }

    override fun equals(other: Any?): Boolean {
    if (this === other) return true
    if (other?.javaClass != javaClass) return false

    other as User

    if (_id != other._id) return false

    return true
    }

    override fun hashCode(): Int {
    return _id.hashCode()
    }
    }
    // ------------ Classes:

    class Name() : Parcelable {
    data class RedditNews(
    val after: String,
    val before: String,
    val news: List<RedditNewsItem>) : Parcelable {

    companion object {
    val CREATOR = createParcel { Name(it) }
    }

    lateinit var first: String
    lateinit var last: String

    protected constructor(parcelIn: Parcel) : this() {
    this.first = parcelIn.readString()
    this.last = parcelIn.readString()
    val CREATOR = createParcel { RedditNews(it) }
    }

    override fun describeContents(): Int {
    return 0
    }
    protected constructor(parcelIn: Parcel) : this(
    parcelIn.readString(),
    parcelIn.readString(),
    listOf<RedditNewsItem>().apply {
    parcelIn.readTypedList(this, RedditNewsItem.CREATOR)
    }
    )

    override fun writeToParcel(dest: Parcel, flags: Int) {
    dest.writeString(first)
    dest.writeString(last)
    dest.writeString(after)
    dest.writeString(before)
    dest.writeTypedList(news)
    }

    override fun equals(other: Any?): Boolean {
    if (this === other) return true
    if (other?.javaClass != javaClass) return false

    other as Name

    if (first != other.first) return false
    if (last != other.last) return false

    return true
    }

    override fun hashCode(): Int {
    var result = first.hashCode()
    result += 31 * result + last.hashCode()
    return result
    }
    override fun describeContents() = 0
    }

    class Additional() : Parcelable {
    data class RedditNewsItem(
    val author: String,
    val title: String,
    val numComments: Int,
    val created: Long,
    val thumbnail: String,
    val url: String
    ) : Parcelable {

    companion object {
    val CREATOR = createParcel { Additional(it) }
    val CREATOR = createParcel { RedditNewsItem(it) }
    }

    lateinit var licensePlate: String

    protected constructor(parcelIn: Parcel) : this() {
    this.licensePlate = parcelIn.readString()
    }
    protected constructor(parcelIn: Parcel) : this(
    parcelIn.readString(),
    parcelIn.readString(),
    parcelIn.readInt(),
    parcelIn.readLong(),
    parcelIn.readString(),
    parcelIn.readString()
    )

    override fun writeToParcel(dest: Parcel, flags: Int) {
    dest.writeString(this.licensePlate)
    }

    override fun describeContents(): Int {
    return 0
    }

    override fun equals(other: Any?): Boolean {
    if (this === other) return true
    if (other?.javaClass != javaClass) return false

    other as Additional

    if (licensePlate != other.licensePlate) return false

    return true
    dest.writeString(author)
    dest.writeString(title)
    dest.writeInt(numComments)
    dest.writeLong(created)
    dest.writeString(thumbnail)
    dest.writeString(url)
    }

    override fun hashCode(): Int {
    return licensePlate.hashCode()
    }
    override fun describeContents() = 0
    }
  2. @juanchosaravia juanchosaravia revised this gist Dec 12, 2015. 1 changed file with 5 additions and 0 deletions.
    5 changes: 5 additions & 0 deletions KotlinParcelable
    Original file line number Diff line number Diff line change
    @@ -10,6 +10,11 @@ fun <T : Parcelable> Parcel.readParcelable(creator: Parcelable.Creator<T>): T? {
    if (readString() != null) return creator.createFromParcel(this) else return null
    }

    // IMPORTANT NOTE:
    // data class: does not support empty primary constructors and doesn't allow the use of lateinit modifier in the constructor.
    // That's why I ended up using regular classes and generating the equal and hash method with Android Studio.
    // I don't really like the idea of not using data classes but I prefer to avoid doing null checks while trying to use this models.


    // EXAMPLE with custom classes

  3. @juanchosaravia juanchosaravia revised this gist Dec 12, 2015. 1 changed file with 70 additions and 22 deletions.
    92 changes: 70 additions & 22 deletions KotlinParcelable
    Original file line number Diff line number Diff line change
    @@ -13,20 +13,24 @@ fun <T : Parcelable> Parcel.readParcelable(creator: Parcelable.Creator<T>): T? {

    // EXAMPLE with custom classes

    data class User(
    var _id: String? = null,
    var email: String? = null,
    var name: Name? = null,
    var phone: String? = null,
    var additional: Additional? = null
    ) : Parcelable {
    class User() : Parcelable {

    companion object {
    val CREATOR = createParcel { User(it) }
    }

    lateinit var _id: String
    lateinit var email: String
    lateinit var name: Name
    lateinit var phone: String
    lateinit var additional: Additional

    protected constructor(parcelIn: Parcel) : this() {
    this._id = parcelIn.readString()
    this.email = parcelIn.readString()
    this.name = parcelIn.readParcelable(Name.CREATOR)
    this.name = parcelIn.readParcelable(Name.CREATOR) ?: Name()
    this.phone = parcelIn.readString()
    this.additional = parcelIn.readParcelable(Additional.CREATOR)
    this.additional = parcelIn.readParcelable(Additional.CREATOR) ?: Additional()
    }

    override fun describeContents(): Int {
    @@ -41,15 +45,30 @@ data class User(
    dest.writeParcelable(additional, 0)
    }

    companion object {
    val CREATOR = createParcel { User(it) }
    override fun equals(other: Any?): Boolean {
    if (this === other) return true
    if (other?.javaClass != javaClass) return false

    other as User

    if (_id != other._id) return false

    return true
    }

    override fun hashCode(): Int {
    return _id.hashCode()
    }
    }

    data class Name(
    var first: String? = null,
    var last: String? = null
    ) : Parcelable {
    class Name() : Parcelable {

    companion object {
    val CREATOR = createParcel { Name(it) }
    }

    lateinit var first: String
    lateinit var last: String

    protected constructor(parcelIn: Parcel) : this() {
    this.first = parcelIn.readString()
    @@ -65,14 +84,32 @@ data class Name(
    dest.writeString(last)
    }

    companion object {
    val CREATOR = createParcel { Name(it) }
    override fun equals(other: Any?): Boolean {
    if (this === other) return true
    if (other?.javaClass != javaClass) return false

    other as Name

    if (first != other.first) return false
    if (last != other.last) return false

    return true
    }

    override fun hashCode(): Int {
    var result = first.hashCode()
    result += 31 * result + last.hashCode()
    return result
    }
    }

    data class Additional(
    var licensePlate: String? = null
    ) : Parcelable {
    class Additional() : Parcelable {

    companion object {
    val CREATOR = createParcel { Additional(it) }
    }

    lateinit var licensePlate: String

    protected constructor(parcelIn: Parcel) : this() {
    this.licensePlate = parcelIn.readString()
    @@ -86,7 +123,18 @@ data class Additional(
    return 0
    }

    companion object {
    val CREATOR = createParcel { Additional(it) }
    override fun equals(other: Any?): Boolean {
    if (this === other) return true
    if (other?.javaClass != javaClass) return false

    other as Additional

    if (licensePlate != other.licensePlate) return false

    return true
    }

    override fun hashCode(): Int {
    return licensePlate.hashCode()
    }
    }
  4. @juanchosaravia juanchosaravia revised this gist Dec 12, 2015. 1 changed file with 61 additions and 2 deletions.
    63 changes: 61 additions & 2 deletions KotlinParcelable
    Original file line number Diff line number Diff line change
    @@ -1,12 +1,51 @@
    // Inline function to create Parcel
    // Inline function to create Parcel Creator
    inline fun <reified T : Parcelable> createParcel(crossinline createFromParcel: (Parcel) -> T?): Parcelable.Creator<T> =
    object : Parcelable.Creator<T> {
    override fun createFromParcel(source: Parcel): T? = createFromParcel(source)
    override fun newArray(size: Int): Array<out T?> = arrayOfNulls(size)
    }

    // custom readParcelable to avoid reflection
    fun <T : Parcelable> Parcel.readParcelable(creator: Parcelable.Creator<T>): T? {
    if (readString() != null) return creator.createFromParcel(this) else return null
    }


    // class example
    // EXAMPLE with custom classes

    data class User(
    var _id: String? = null,
    var email: String? = null,
    var name: Name? = null,
    var phone: String? = null,
    var additional: Additional? = null
    ) : Parcelable {

    protected constructor(parcelIn: Parcel) : this() {
    this._id = parcelIn.readString()
    this.email = parcelIn.readString()
    this.name = parcelIn.readParcelable(Name.CREATOR)
    this.phone = parcelIn.readString()
    this.additional = parcelIn.readParcelable(Additional.CREATOR)
    }

    override fun describeContents(): Int {
    return 0
    }

    override fun writeToParcel(dest: Parcel, flags: Int) {
    dest.writeString(_id)
    dest.writeString(email)
    dest.writeParcelable(name, 0)
    dest.writeString(phone)
    dest.writeParcelable(additional, 0)
    }

    companion object {
    val CREATOR = createParcel { User(it) }
    }
    }

    data class Name(
    var first: String? = null,
    var last: String? = null
    @@ -29,5 +68,25 @@ data class Name(
    companion object {
    val CREATOR = createParcel { Name(it) }
    }
    }

    data class Additional(
    var licensePlate: String? = null
    ) : Parcelable {

    protected constructor(parcelIn: Parcel) : this() {
    this.licensePlate = parcelIn.readString()
    }

    override fun writeToParcel(dest: Parcel, flags: Int) {
    dest.writeString(this.licensePlate)
    }

    override fun describeContents(): Int {
    return 0
    }

    companion object {
    val CREATOR = createParcel { Additional(it) }
    }
    }
  5. @juanchosaravia juanchosaravia created this gist Dec 12, 2015.
    33 changes: 33 additions & 0 deletions KotlinParcelable
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,33 @@
    // Inline function to create Parcel
    inline fun <reified T : Parcelable> createParcel(crossinline createFromParcel: (Parcel) -> T?): Parcelable.Creator<T> =
    object : Parcelable.Creator<T> {
    override fun createFromParcel(source: Parcel): T? = createFromParcel(source)
    override fun newArray(size: Int): Array<out T?> = arrayOfNulls(size)
    }


    // class example
    data class Name(
    var first: String? = null,
    var last: String? = null
    ) : Parcelable {

    protected constructor(parcelIn: Parcel) : this() {
    this.first = parcelIn.readString()
    this.last = parcelIn.readString()
    }

    override fun describeContents(): Int {
    return 0
    }

    override fun writeToParcel(dest: Parcel, flags: Int) {
    dest.writeString(first)
    dest.writeString(last)
    }

    companion object {
    val CREATOR = createParcel { Name(it) }
    }

    }