Git Product home page Git Product logo

serialization-parcelable's Introduction

serialization-parcelable

parcelable

Android Parceling support for the Kotlinx Serialization library.
GitHub tag (latest by date) Badge

// Add to Android Intent
intent.putExtra(name = "com.example.MyModel", value = myModel, serializer = MyModel.serializer())

// Retrieve from Android Intent
val result = intent.getParcelableExtra(name = "com.example.MyModel", deserializer = MyModel.serializer())

check(result == myModel) // True

// Compose
val result = rememberSavable(serializer = MyModel.serializer()) { MyModel(...) }

All serialization for an Android or Multi-platform project can be handled from a single library, no need to create both custom Android Parcelers and Serializers. Use the Kotlinx Serialization library, and it will automatically work with Android's Parcel, Bundle, and Intent.

Getting Started ๐Ÿ

The library is provided through Repsy.io. Checkout the releases page to get the latest version.
GitHub tag (latest by date)

Repository

repositories {
    maven { url = uri("https://repo.repsy.io/mvn/chrynan/public") }
}

Dependency

Core

implementation("com.chrynan.parcelable:parcelable-core:$VERSION")

Compose

implementation("com.chrynan.parcelable:parcelable-compose:$VERSION")

Usage ๐Ÿ‘จโ€๐Ÿ’ป

Set up the Parcelable object

Similar to the Json object introduced by the Kotlinx Serialization library, this library introduces a Parcelable object. The extension functions default to using the Parcelable.Default value if a Parcelable instance is not provided, but if customization is required, an instance can be created as follows:

val parcelable = Parcelable {
    serializersModule = mySerializersModule
}

Utilize the Kotlinx Serialization to serialize your model classes. These classes can then be used with Android's Bundle, Intent, and Parcel objects.

@Serializable
data class MyModel(
    val intField: Int,
    val stringField: String,
    val nullableStringField: String? = null
)

Encode and decode models

Intents and Bundles

// Put
intent.putExtra(key, myModel, parcelable)
bundle.putParcelable(key, myModel, parcelable)

// Get
val myModel = intent.getParcelableExtra(key, parcelable)
val myModel = bundle.getParcelable(key, parcelable)

Parcels and Bundles

// To
parcelable.encodeToParcel(parcel, myModel)
val bundle = parcelable.encodeToBundle(myModel)

// From
val myModel = parcelable.decodeFromParcel(parcel)
val myModel = parcelable.decodeFromBundle(bundle)

Saver with Jetpack Compose

val model = rememberSavable(parcelable = parcelable, serializer = MyModel.serializer) { myModel }

Multiplatform

This library is a Kotlin Multi-platform library and supports Android, iOS, JVM, and JS Kotlin targets. The Parcelable and Parcel objects are available in the common source set and can be used to encode and decode models. Then, in platform specific code, the Parcels can be stored and retrieved between different components (ex: Android Intents).

// Common Code
val parcel = parcelable.encodeToParcel(serializer = MyModel.serializer(), value = myModel)

// Android Code
Bundle().readFromParcel(parcel)

Documentation ๐Ÿ“ƒ

More detailed documentation is available in the docs folder. The entry point to the documentation can be found here.

Sample

The sample-android module contains an Android App showcasing the use of this library and providing a means to test parceling different models.

Simply update the ExpectedModel.model value to be any Serializable class and run the application to test if the parceling worked.

Sample Screenshots

Main Screen Results Screen

Security ๐Ÿ›ก๏ธ

For security vulnerabilities, concerns, or issues, please responsibly disclose the information either by opening a public GitHub Issue or reaching out to the project owner.

Contributing โœ๏ธ

Outside contributions are welcome for this project. Please follow the code of conduct and coding conventions when contributing. If contributing code, please add thorough documents. and tests. Thank you!

Sponsorship โค๏ธ

Support this project by becoming a sponsor of my work! And make sure to give the repository a โญ

License โš–๏ธ

Copyright 2021 chRyNaN

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

serialization-parcelable's People

Contributors

chrynan avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

serialization-parcelable's Issues

Parcelize serializable data is broken

Describe the bug
When I'm trying to transfer Serializable data through Bundle, I use methods putParcelable and getParcelable to parcelize it but the result data is broken.

To Reproduce
Params:

@Serializable
data class Params(val intro: Boolean)
val params = Params(true)
val bundle = Bundle()
bundle.putParcelable("key", params)
bundle.getParcelable("key")

Result behavior
Params(false)

Expected behavior
Params(true)

val params = Params(false)
val bundle = Bundle()
bundle.putParcelable("key", params)
bundle.getParcelable("key")

Result behavior
null

Expected behavior
Params(false)

Additional context
Serialization-parcelable - 0.5.1 (version 0.5.0 works fine)
Kotlin - 1.7.20
Kotlin-serialization - 1.4.1

Decoding nullable types from Bundle

Describe the bug

The Parcelable.decodeFromBundle() functions impose an upper bound of <T : Any> on the value type, which doesn't mirror the decodeFromByteArray and decodeFromParcel functions.

I'm optimistic that the : Any bound could simply be removed, as it's the serializer's job to encode/decode null and not-null marks.

NPE in ByteArrayParcel init

The init block in ByteArrayParcel throws an NPE because data is not set when setDataFromByteArray runs.

I'm not sure if this is caused by a compiler change in Kotlin 1.7, because ordinarily you'd get a compiler diagnostic like "data is not initialized".

The easiest fix would be to move the init { } block below where the data property is initialized.

Stacktrace:

Cannot invoke "java.util.List.clear()" because "this.data" is null
java.lang.NullPointerException: Cannot invoke "java.util.List.clear()" because "this.data" is null
	at com.chrynan.parcelable.core.ByteArrayParcel.setDataFromByteArray(ByteArrayParcel.kt:188)
	at com.chrynan.parcelable.core.ByteArrayParcel.<init>(ByteArrayParcel.kt:17)
	at com.chrynan.parcelable.core.ByteArrayParcel.<init>(ByteArrayParcel.kt:14)
	at com.chrynan.parcelable.core.JvmParcelKt.Parcel(JvmParcel.kt:3)

Unmarshalling unknown type code 7340148 at offset 8

Describe the bug
There is a bug in library that happens only on Pixel devices.

Fatal Exception: java.lang.RuntimeException: Parcel android.os.Parcel@52c801c: Unmarshalling unknown type code 6357038 at offset 8
at android.os.Parcel.readValue(Parcel.java:3305)
at android.os.Parcel.readArrayMapInternal(Parcel.java:3623)
at android.os.BaseBundle.initializeFromParcelLocked(BaseBundle.java:292)
at android.os.BaseBundle.unparcel(BaseBundle.java:236)
at android.os.Bundle.filterValues(Bundle.java:395)
at android.os.Bundle.filterValues(Bundle.java:405)
at android.content.Intent.removeUnsafeExtras(Intent.java:8859)
at android.app.ActivityThread.handleRequestAssistContextExtras(ActivityThread.java:3890)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2171)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loopOnce(Looper.java:201)
at android.os.Looper.loop(Looper.java:288)
at android.app.ActivityThread.main(ActivityThread.java:7839)
at java.lang.reflect.Method.invoke(Method.java)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)

I can't reproduce it, but we have a lot of bugs in firebase crashlytics. With no specific case, any screen with your parcelable between intents/fragments inside intent is potential threat.

Smartphone (please complete the following information):

  • Device: any Pixel
  • OS: android 12

Additional context
It is happening with version 0.3.1, I have simultaneously upgraded to 0.4.1 and will give feedback whether it still happens.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.