Skip to content

Commit

Permalink
Fixes #60
Browse files Browse the repository at this point in the history
  • Loading branch information
Rafael Costa committed Feb 17, 2022
1 parent ea4d28c commit e15ac48
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import com.ramcosta.samples.destinationstodosample.ui.screens.destinations.GoToP
import com.ramcosta.samples.destinationstodosample.ui.screens.destinations.ProfileScreenDestination
import com.ramcosta.samples.destinationstodosample.ui.screens.destinations.TestScreenDestination
import com.ramcosta.samples.destinationstodosample.ui.screens.profile.Stuff
import com.ramcosta.samples.destinationstodosample.ui.screens.profile.Things
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch

Expand All @@ -46,6 +47,7 @@ fun GreetingScreen(
id = 3,
groupName = "%02%03",
stuff = Stuff.STUFF2,
things = Things()
)
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ data class ProfileScreenNavArgs(
val id: Long,
val stuff: Stuff = Stuff.STUFF1,
val groupName: String = DEFAULT_GROUP,
val things: Things?,
val things: ArgumentThings?,
val serializableExample: SerializableExample? = null
)

Expand All @@ -22,11 +22,13 @@ enum class Stuff {
STUFF2
}

interface ArgumentThings: Parcelable

@Parcelize
data class Things(
val thing1: String = "QWEQWEQWE",
val thing2: String = "ASDASDASD"
) : Parcelable
) : ArgumentThings

data class SerializableExample(
val thing1: String = "SERIALIZABLE/11/1",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import android.os.Parcel
import android.os.Parcelable
import com.ramcosta.composedestinations.utils.base64ToByteArray
import com.ramcosta.composedestinations.utils.toBase64Str
import java.lang.reflect.Modifier

/**
* Default [ParcelableNavTypeSerializer] which converts the parcelable to Base64 strings
Expand All @@ -17,11 +18,21 @@ import com.ramcosta.composedestinations.utils.toBase64Str
class DefaultParcelableNavTypeSerializer : ParcelableNavTypeSerializer<Parcelable> {

override fun toRouteString(value: Parcelable): String {
return value.toBase64()
return value.javaClass.name + "@" + value.toBase64()
}

override fun fromRouteString(routeStr: String, jClass: Class<out Parcelable>): Parcelable {
return base64ToParcelable(routeStr, jClass)
val (className, base64) = routeStr.split("@").let { it[0] to it[1] }

val creator = if (jClass.isFinal) {
// Since we have this, small optimization to avoid additional reflection call of Class.forName
jClass.parcelableCreator
} else {
// If our class is not final, then we must use the actual class from "className"
parcelableClassForName(className).parcelableCreator
}

return base64ToParcelable(base64, creator)
}

private fun Parcelable.toBase64(): String {
Expand All @@ -33,10 +44,10 @@ class DefaultParcelableNavTypeSerializer : ParcelableNavTypeSerializer<Parcelabl
return bytes.toBase64Str()
}

private fun <T> base64ToParcelable(base64: String, jClass: Class<T>): T {
private fun <T> base64ToParcelable(base64: String, creator: Parcelable.Creator<T>): T {
val bytes = base64.base64ToByteArray()
val parcel = unmarshall(bytes)
val result = jClass.parcelableCreator.createFromParcel(parcel)
val result = creator.createFromParcel(parcel)
parcel.recycle()
return result
}
Expand All @@ -60,4 +71,12 @@ class DefaultParcelableNavTypeSerializer : ParcelableNavTypeSerializer<Parcelabl
throw BadParcelableException(t.message)
}
}

@Suppress("UNCHECKED_CAST")
private fun parcelableClassForName(className: String): Class<out Parcelable> {
return Class.forName(className) as Class<out Parcelable>
}

private val Class<out Parcelable>.isFinal get() =
!isInterface && Modifier.isFinal(modifiers)
}

0 comments on commit e15ac48

Please sign in to comment.