From 94c8fa4f464ed0871dd8b73cd1d41c935dc85d7a Mon Sep 17 00:00:00 2001 From: WilliamKwokX <1425183716@qq.com> Date: Wed, 13 Sep 2023 19:59:10 +0800 Subject: [PATCH] v1.0.5 --- api/build.gradle | 2 +- .../java/pers/shawxingkwok/mvb/MyFragment.kt | 6 ++- .../pers/shawxingkwok/mvb/android/Saver.kt | 22 ++++++++- .../android/convertParcelableArrayIfNeeded.kt | 18 ++++++++ .../pers/shawxingkwok/mvb/android/observe.kt | 1 - .../pers/shawxingkwok/mvb/android/save.kt | 43 +++++++++++------- demo/build.gradle | 3 +- .../caches-jvm/inputs/source-to-output.tab | Bin 4096 -> 4096 bytes .../inputs/source-to-output.tab.values.at | Bin 11776 -> 22020 bytes .../jvm/kotlin/class-attributes.tab | Bin 4096 -> 4096 bytes .../jvm/kotlin/class-attributes.tab.values.at | Bin 85 -> 97 bytes .../jvm/kotlin/class-fq-name-to-source.tab | Bin 4096 -> 4096 bytes .../class-fq-name-to-source.tab.values.at | Bin 1223 -> 1596 bytes .../jvm/kotlin/internal-name-to-source.tab | Bin 4096 -> 4096 bytes .../internal-name-to-source.tab.values.at | Bin 7302 -> 13907 bytes .../cacheable/caches-jvm/jvm/kotlin/proto.tab | Bin 4096 -> 4096 bytes .../caches-jvm/jvm/kotlin/proto.tab.values.at | Bin 6747 -> 12209 bytes .../jvm/kotlin/source-to-classes.tab | Bin 4096 -> 4096 bytes .../kotlin/source-to-classes.tab.values.at | Bin 6701 -> 12636 bytes .../caches-jvm/jvm/kotlin/subtypes.tab | Bin 4096 -> 4096 bytes .../jvm/kotlin/subtypes.tab.values.at | Bin 761 -> 988 bytes .../caches-jvm/jvm/kotlin/supertypes.tab | Bin 4096 -> 4096 bytes .../jvm/kotlin/supertypes.tab.values.at | Bin 432 -> 583 bytes .../cacheable/caches-jvm/lookups/counters.tab | 2 +- .../caches-jvm/lookups/file-to-id.tab | Bin 4096 -> 4096 bytes .../lookups/file-to-id.tab.values.at | Bin 97 -> 121 bytes .../caches-jvm/lookups/id-to-file.tab | Bin 4096 -> 4096 bytes .../lookups/id-to-file.tab.keystream | Bin 4096 -> 4096 bytes .../lookups/id-to-file.tab.keystream.len | Bin 8 -> 8 bytes .../caches-jvm/lookups/id-to-file.tab.len | Bin 8 -> 8 bytes .../lookups/id-to-file.tab.values.at | Bin 716 -> 1089 bytes .../caches-jvm/lookups/id-to-file.tab_i | Bin 32768 -> 32768 bytes .../cacheable/caches-jvm/lookups/lookups.tab | Bin 16384 -> 16384 bytes .../caches-jvm/lookups/lookups.tab.values.at | Bin 14657 -> 29078 bytes .../cacheable/last-build.bin | Bin 18 -> 18 bytes .../local-state/build-history.bin | Bin 4035 -> 4311 bytes .../androidutil/view/ParcelableComponent.kt | 31 +++++++++++++ .../androidutil/view/SaveLiveData.kt | 6 --- .../view/SaveWithParcelableComponents.kt | 33 -------------- restoretest/build.gradle | 1 + .../restoretest/ExampleInstrumentedTest.kt | 7 --- .../shawxingkwok/restoretest/MainActivity.kt | 43 +++++++++++++----- .../java/pers/shawxingkwok/restoretest/P.kt | 3 +- .../java/pers/shawxingkwok/restoretest/Q.kt | 10 ++++ 44 files changed, 147 insertions(+), 84 deletions(-) create mode 100644 api/src/main/java/pers/shawxingkwok/mvb/android/convertParcelableArrayIfNeeded.kt create mode 100644 demo/src/androidTest/java/pers/shawxingkwok/androidutil/view/ParcelableComponent.kt delete mode 100644 demo/src/androidTest/java/pers/shawxingkwok/androidutil/view/SaveWithParcelableComponents.kt create mode 100644 restoretest/src/main/java/pers/shawxingkwok/restoretest/Q.kt diff --git a/api/build.gradle b/api/build.gradle index aa56196..db7d850 100644 --- a/api/build.gradle +++ b/api/build.gradle @@ -63,7 +63,7 @@ tasks.withType(KotlinCompile).configureEach{ // publish mavenPublishing { def artifactId = "mvb-android" - def version = "1.0.4" + def version = "1.0.5" def isSnapshot = false if (isSnapshot) version += "-SNAPSHOT" diff --git a/api/src/androidTest/java/pers/shawxingkwok/mvb/MyFragment.kt b/api/src/androidTest/java/pers/shawxingkwok/mvb/MyFragment.kt index 54001ca..75ee3bd 100644 --- a/api/src/androidTest/java/pers/shawxingkwok/mvb/MyFragment.kt +++ b/api/src/androidTest/java/pers/shawxingkwok/mvb/MyFragment.kt @@ -3,9 +3,11 @@ package pers.shawxingkwok.mvb import androidx.fragment.app.Fragment -import androidx.lifecycle.ViewModel import kotlinx.coroutines.flow.MutableStateFlow -import pers.shawxingkwok.mvb.android.* +import pers.shawxingkwok.mvb.android.observe +import pers.shawxingkwok.mvb.android.rmb +import pers.shawxingkwok.mvb.android.saveMutableStateFlow +import pers.shawxingkwok.mvb.android.transform internal class MyFragment : Fragment() { val arr by rmb { intArrayOf(1, 2) } diff --git a/api/src/main/java/pers/shawxingkwok/mvb/android/Saver.kt b/api/src/main/java/pers/shawxingkwok/mvb/android/Saver.kt index f62a262..4cf1819 100644 --- a/api/src/main/java/pers/shawxingkwok/mvb/android/Saver.kt +++ b/api/src/main/java/pers/shawxingkwok/mvb/android/Saver.kt @@ -4,6 +4,7 @@ import android.annotation.SuppressLint import android.os.Parcel import android.os.Parcelable import pers.shawxingkwok.ktutil.updateIf +import kotlin.reflect.KClass internal class Saver( var value: Any?, @@ -21,8 +22,21 @@ internal class Saver( } companion object CREATOR : Parcelable.Creator { - var parcelableLoader: ClassLoader? = null - var recover: ((Any?) -> Any?)? = null + private var parcelableComponent: KClass? = null + private var parcelableLoader: ClassLoader? = null + private var recover: ((Any?) -> Any?)? = null + + fun prepare(parcelableComponent: KClass?, recover: ((Any?) -> Any?)?){ + this.parcelableComponent = parcelableComponent + parcelableLoader = parcelableComponent?.java?.classLoader + this.recover = recover + } + + fun clear(){ + parcelableComponent = null + parcelableLoader = null + recover = null + } override fun createFromParcel(parcel: Parcel): Saver { @SuppressLint("ParcelClassLoader") @@ -33,6 +47,10 @@ internal class Saver( UNINITIALIZED else parcel.readValue(parcelableLoader) + // convert Parcelable[] to the actual. + // However, the inner Parcelable[] can't be parsed here. + // This problem could only be fixed by the authority. + .convertParcelableArrayIfNeeded(parcelableComponent) .updateIf({ recover != null }){ recover!!(it) } return Saver(value) diff --git a/api/src/main/java/pers/shawxingkwok/mvb/android/convertParcelableArrayIfNeeded.kt b/api/src/main/java/pers/shawxingkwok/mvb/android/convertParcelableArrayIfNeeded.kt new file mode 100644 index 0000000..b5bb834 --- /dev/null +++ b/api/src/main/java/pers/shawxingkwok/mvb/android/convertParcelableArrayIfNeeded.kt @@ -0,0 +1,18 @@ +package pers.shawxingkwok.mvb.android + +import android.os.Parcelable +import java.util.* +import kotlin.reflect.KClass + +@Suppress("UNCHECKED_CAST") +@PublishedApi +internal fun T.convertParcelableArrayIfNeeded(parcelableComponent: KClass?): T = + if (this is Array<*> && javaClass.componentType == Parcelable::class.java) { + requireNotNull(parcelableComponent){ + "The parcelable component misses." + } + val newArrClass = java.lang.reflect.Array.newInstance(parcelableComponent.java, size).javaClass as Class> + Arrays.copyOf(this, size, newArrClass) as T + } + else + this \ No newline at end of file diff --git a/api/src/main/java/pers/shawxingkwok/mvb/android/observe.kt b/api/src/main/java/pers/shawxingkwok/mvb/android/observe.kt index ff8e552..4a232d0 100644 --- a/api/src/main/java/pers/shawxingkwok/mvb/android/observe.kt +++ b/api/src/main/java/pers/shawxingkwok/mvb/android/observe.kt @@ -1,6 +1,5 @@ package pers.shawxingkwok.mvb.android -import androidx.fragment.app.Fragment import androidx.lifecycle.* import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.Flow diff --git a/api/src/main/java/pers/shawxingkwok/mvb/android/save.kt b/api/src/main/java/pers/shawxingkwok/mvb/android/save.kt index 69fecbd..303fdc8 100644 --- a/api/src/main/java/pers/shawxingkwok/mvb/android/save.kt +++ b/api/src/main/java/pers/shawxingkwok/mvb/android/save.kt @@ -12,6 +12,17 @@ import java.io.Serializable import java.util.* import kotlin.reflect.KClass +@PublishedApi +internal val KClass<*>.parcelableComponent: KClass? get() { + fun Class<*>.isParcelable(): Boolean = + Parcelable::class.java.isAssignableFrom(this) + + return if (this.java.isParcelable()) + this as KClass + else + java.componentType?.takeIf { it.isParcelable() }?.kotlin as KClass? +} + public class SavableMVBData @PublishedApi internal constructor( public var parcelableComponent: KClass?, @PublishedApi internal var savedType: KClass, @@ -29,8 +40,10 @@ public class SavableMVBData @PublishedApi internal constructor( when(val bundle = state.get(key)){ null -> Saver(UNINITIALIZED, convert).also { state[key] = bundleOf("" to it) } else -> { - Saver.parcelableLoader = (parcelableComponent ?: savedType.parcelableComponent)?.java?.classLoader - Saver.recover = recover + Saver.prepare( + parcelableComponent = parcelableComponent ?: savedType.parcelableComponent, + recover = recover, + ) val saver = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) @@ -38,8 +51,9 @@ public class SavableMVBData @PublishedApi internal constructor( else bundle.getParcelable("")!! - Saver.recover = null - // update [convert] to remove any possible references to old [thisRef]. + Saver.clear() + + // update [convert] to remove any possible reference to old [thisRef]. saver.convert = convert saver } @@ -47,18 +61,6 @@ public class SavableMVBData @PublishedApi internal constructor( } } -@PublishedApi -internal val KClass<*>.parcelableComponent: KClass? get(){ - if (Parcelable::class.java.isAssignableFrom(this.java)) - return this as KClass - - val component = java.componentType ?: return null - if (Parcelable::class.java.isAssignableFrom(component)) - return component.kotlin as KClass - - return null -} - /** * See [doc](https://shawxingkwok.github.io/ITWorks/docs/multiplatform/mvb/android/#save). */ @@ -122,6 +124,7 @@ public inline fun LV.saveMutableStateFlow( /** * See [doc](https://shawxingkwok.github.io/ITWorks/docs/multiplatform/mvb/android/#save). */ +@Suppress("NAME_SHADOWING") public inline fun LV.saveMutableSharedFlow( parcelableComponent: KClass? = null, replay: Int = 0, @@ -139,10 +142,16 @@ public inline fun LV.saveMutableSharedFlow( convert = { it.replayCache }, recover = { cache -> val flow = MutableSharedFlow(replay, extraBufferCapacity, onBufferOverflow) - cache.forEach(flow::tryEmit) + + val parcelableComponent = parcelableComponent ?: T::class.parcelableComponent + + cache.map{ it.convertParcelableArrayIfNeeded(parcelableComponent) } + .forEach(flow::tryEmit) + flow } ) + // This part is essential. .also { if (it.parcelableComponent == null) it.parcelableComponent = T::class.parcelableComponent diff --git a/demo/build.gradle b/demo/build.gradle index 1904a9a..ca940ca 100644 --- a/demo/build.gradle +++ b/demo/build.gradle @@ -47,9 +47,10 @@ dependencies { implementation libs.viewbindingKtx testImplementation libs.junit - androidTestImplementation libs.kotlin.reflect + androidTestImplementation(libs.androidx.fragment.test) androidTestImplementation libs.androidx.test.ext.junit androidTestImplementation libs.espresso.core + androidTestImplementation libs.kotlin.reflect } //region shawxingkwok: mvb diff --git a/demo/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab b/demo/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab index dbc77c4806b28b55ab2b2207bb42eeb299d037ba..677034459976d7f2504ca9645f5ee8e0ea047ef2 100644 GIT binary patch delta 72 zcmZorXi(ss?X#PYm4ShQeIlo}q%e@d2*p4O4A_CB!bD$tuGL5W|DOlsv~8O>O^&7H P=>Pv458CrjEZ_tH*8>sQ delta 72 zcmZorXi(ss?X#PYnSp_Ubt0#>Bs-A72*p4O3_xNc6MgNuR37~QKM%cx&A^CTFU={#gwg-p+ delta 7 OcmZo!!`KkBKo0;6G6LKH diff --git a/demo/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab b/demo/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab index 089410b916952bd427cba2b0e44d7165aacb825e..843edce02c4440937c85bc2058d2526c0a25f576 100644 GIT binary patch delta 76 zcmZorXi(ss?X#PYm4ShQdm^W{BoC0m2*p4O47h>h{E5Edl1u*o|9=w5*$<>Y0qIph NS_i0l;l{nr`~X%?6*~X` delta 76 zcmZorXi(ss?X#PYnSp_Ub0VjO|jg$+iFg|33-j><7}HfHaW$ NuLD&5f8$U diff --git a/demo/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.values.at b/demo/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.values.at index f5ff014ccde07c8bc586132a0e3793c13b166ca4..ecd6c704b340a54f3483510ac5c44ff5182bacc6 100644 GIT binary patch delta 7 OcmWGdoDe$Efd>E!0|I#f delta 4 LcmYccoe&BD1N;G; diff --git a/demo/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab b/demo/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab index 2360f58ea72e3018d5f46cd4f0b607fbff20944f..9d2c7bb043fae8fa3aa59874a2c6e2418039c53c 100644 GIT binary patch delta 77 zcmZorXi(ss?X#PYm4ShQdm^W{q!5t72*p4O47h=0;Y8nXsq$a{|DObM0{{L0{|QK2 R{Qm!62dG-**T#KL`~XoU6nX#v delta 77 zcmZorXi(ss?X#PYnSp_Ub0Vji_>Y?sMV?0A3#!8UO$Q diff --git a/demo/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.values.at b/demo/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.values.at index 096bc488438feac764c3a78e9c06257455b46bbc..acdaf987b238f4661c1ffd77cbb3831569c68371 100644 GIT binary patch delta 43 vcmX@kxrb-NaTew{hSp diff --git a/demo/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab b/demo/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab index 5d4ffb5ace355ee1ad60822de4278755f4910fe6..8d18f89c3342b2c3c2b51ca0b4698cd86a99b5b1 100644 GIT binary patch literal 4096 zcmeIwJxE(o7{>88u~pk9+NGdF5ky3A5kW9GSc=dL;?T5{lelQ>N2aPBq7Dv%iwII} zmwTuvt>P0{Ea~R){e2+N~yD+;hWiW;>pYZ)SkIQMPBw*Hx{dh^RNu0t!(5xOK znE576;Rnp(GpsB!TUe92F@k$|x+;|yn~mdptii9CPH{olgPr^<0?kk zYcEdW`-^H3bJ!XbN#in>pH;7M8@sDT25}ufpHwTjhv^!T5nRL|7BF8@{lHOds}%|3 z7#1E?*Ki!qu^B^kBF7J^6PU#PMCNfA6PU--JJm?NNKaX{19^R&HTTUx z*zZr97iM3B-#;+p5r4j57R^Z1?`O;n^TtfY{Ph|0(o8n`{j7OtsyWHO;_a8uS diff --git a/demo/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.values.at b/demo/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.values.at index 8c087f345e74d6f7098cb70990f42850baf6466b..7fec81499484b0858c71f9c133c8e5dd090e9f0a 100644 GIT binary patch delta 22 ecmZp(yqvS4O=dGcce&u^7=cXY%@?@evH$>RV+gPS delta 7 Ocmcbd(`LD$O$GoD4g*mD diff --git a/demo/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab b/demo/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab index eb2cbb859ed657c7751773d536cb95b2465df010..b8b9c447bab3a51f79084dccf9483ff609ca2b8d 100644 GIT binary patch delta 90 zcmZorXi(ss?X#PYgMop8b0Vjn%S|9|5}eg26BoB*UJ9J~Mk diff --git a/demo/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.values.at b/demo/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.values.at index 4fb131c14f348b5c57f387f9ab66ebb26f37756b..a18e29c577d9fd5a27ed7e5c5dc6764324e0eb55 100644 GIT binary patch delta 17 Ycmca@vN3)`wA5xvZh8LA*?i_~06y{svj6}9 delta 7 OcmdlOf7@h3v=jgj4+BL2 diff --git a/demo/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab b/demo/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab index c91e85efeed372c321296873d51781aa81e14685..7cecbdbb05d28f89f98b058585e5caf200139ae0 100644 GIT binary patch delta 77 zcmZorXi(ss?X#PYm4ShQYa*w%q#TgJ2*p4O47h-#;Y445DZzXH{~G{hYrg&eUkju! RJ^laxHjtLQwsD&mKL9g06V(6! delta 77 zcmZorXi(ss?X#PYnSp_UVBrA}?2*p4O4A_8V$3$OqCeyzY+tgV81Hs0P{``y# E07|qCyZ`_I diff --git a/demo/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.values.at b/demo/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.values.at index 284e64b00b94c64f65bdd83b7a1ef1f89d448262..2121c5d3bd28c885980dd454262bf46f55a2297e 100644 GIT binary patch delta 37 tcmey#dWU_(PbOw72FrB9n0RaCU4A1}o delta 7 Ocmcb^{*!gXPbL5lDg%uG diff --git a/demo/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab b/demo/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab index 05985b267cde73eca551a471421a5bc7f4400d69..ee2f66c5cd5d85bf23083ea9ad0e03abc2eb6d90 100644 GIT binary patch delta 69 zcmZorXi(ss?X#PYm4ShQb0Vj%fb_BnObe2*p4O4A_CB^h95OnI-@K|2F{2ZUfS_KpIH> PzYV1~9<=A5SilJY%ZeEG diff --git a/demo/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.values.at b/demo/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.values.at index 6a3671f42dc73a4e10c7b13921587fe18801003a..09947d11cdfdfc2105bf384a33da41b1d5ac8ca7 100644 GIT binary patch delta 29 YcmYeSoRBEN!T-bERX~R delta 20 bcmZorXi(r_U}R!uVP#|ADEOX#q5>xXB}@a~ diff --git a/demo/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.keystream.len b/demo/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.keystream.len index d9e6aa615b956553ed1ed6dae0706469d4755209..1ff194f2e9051d3504a0a2f471c66d87c2e41e59 100644 GIT binary patch literal 8 LcmZQz00SNX02BZX literal 8 LcmZQz00RyH01yBP diff --git a/demo/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.len b/demo/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.len index fa606b628b9821e4e1a5e524f5973b5db3fb44ba..a363176c8cf9dbf2868dabc2a7c34c549945aa8a 100644 GIT binary patch literal 8 LcmZQz0D}hr0O$bW literal 8 LcmZQz0D}Vn0LTEr diff --git a/demo/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.values.at b/demo/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.values.at index 6043414dc5c5f15c982c6fdad12171d20eba635f..eaea8d6cb98f9e603664e4b8a6a9b157752c0d06 100644 GIT binary patch delta 31 jcmX@ZdXQto87Ag9hSW$_7*b diff --git a/demo/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab b/demo/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab index 2d98c9f33a2841158a91217397e4e602923528e2..e5b5a91f433ec786857c3bb437dfc8d4f1d09564 100644 GIT binary patch literal 16384 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 QYIdMz2WocU|Fa$VA5F}6P5=M^ diff --git a/demo/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.values.at b/demo/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.values.at index b3e807a5302306ae9088b86dc29b489427edc634..23594ca076e1a228f71a23c96d92fa4a1d70aeea 100644 GIT binary patch literal 29078 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 delta 8 PcmbRCnDJoI21iQ(6H5cw diff --git a/demo/build/kotlin/compileDebugKotlin/cacheable/last-build.bin b/demo/build/kotlin/compileDebugKotlin/cacheable/last-build.bin index 0ece3c037571eb8706b2dc505844dc6a558bc466..e7a0543d63d33a45c2502c1ada17c254e8f042ea 100644 GIT binary patch literal 18 YcmZ4UmVvdLhk=2yt7Gf$84N%G06IYheEse_c^<&07Z6Dh37?1}I?JD9Fmg&ccwcXT*>-*^n_~b1RP>GcN-JV^_!I1MeAu y%9tjzG1>9(`xj-VXXYj5IF|379Lr+F3Y1{50_w1u+{k4k08+p8_Y9DFFaQ8l{}}uL delta 43 tcmcbvcvxO=&07Z6Dh37?1}I?KD9Fmg&b&HZ&xj#wvLR!}=2jj%W&qbf33UJf diff --git a/demo/src/androidTest/java/pers/shawxingkwok/androidutil/view/ParcelableComponent.kt b/demo/src/androidTest/java/pers/shawxingkwok/androidutil/view/ParcelableComponent.kt new file mode 100644 index 0000000..a5c6c03 --- /dev/null +++ b/demo/src/androidTest/java/pers/shawxingkwok/androidutil/view/ParcelableComponent.kt @@ -0,0 +1,31 @@ +@file:Suppress("unused") + +package pers.shawxingkwok.androidutil.view + +import android.os.Parcelable +import android.util.SparseArray +import androidx.fragment.app.Fragment +import kotlinx.parcelize.Parcelize +import pers.shawxingkwok.mvb.android.save + +internal class ParcelableComponent { + internal class MyFragment : Fragment() { + @Parcelize + data class User(val id: Long, val name: String): Parcelable + + /** + * Pass `KClass` (`User::class` in this case) when ultimately + * saved as `List`/`SparseArray`. + * + * 'ultimately' means saved types change with `transform`. + */ + val userList by save(User::class) { mutableListOf() } + val userSparseArr by save(User::class) { SparseArray() } + + /** + * `User::class` could be automatically recognized in cases below. + */ + var user: User by save() + var userArr by save { emptyArray() } + } +} \ No newline at end of file diff --git a/demo/src/androidTest/java/pers/shawxingkwok/androidutil/view/SaveLiveData.kt b/demo/src/androidTest/java/pers/shawxingkwok/androidutil/view/SaveLiveData.kt index b182bf4..0f47430 100644 --- a/demo/src/androidTest/java/pers/shawxingkwok/androidutil/view/SaveLiveData.kt +++ b/demo/src/androidTest/java/pers/shawxingkwok/androidutil/view/SaveLiveData.kt @@ -5,18 +5,12 @@ package pers.shawxingkwok.androidutil.view import androidx.fragment.app.Fragment import androidx.fragment.app.viewModels import androidx.lifecycle.LiveData -import androidx.lifecycle.MutableLiveData import androidx.lifecycle.SavedStateHandle import androidx.lifecycle.ViewModel import androidx.lifecycle.switchMap import pers.shawxingkwok.mvb.android.rmb -import pers.shawxingkwok.mvb.android.save import pers.shawxingkwok.mvb.android.saveMutableLiveData -fun getFilteredData(query: String): LiveData> { - TODO() -} - class SaveLiveData{ class MyViewModel(private val state: SavedStateHandle) : ViewModel(){ val filteredData: LiveData> = diff --git a/demo/src/androidTest/java/pers/shawxingkwok/androidutil/view/SaveWithParcelableComponents.kt b/demo/src/androidTest/java/pers/shawxingkwok/androidutil/view/SaveWithParcelableComponents.kt deleted file mode 100644 index 1e6ff85..0000000 --- a/demo/src/androidTest/java/pers/shawxingkwok/androidutil/view/SaveWithParcelableComponents.kt +++ /dev/null @@ -1,33 +0,0 @@ -@file:Suppress("unused", "MemberVisibilityCanBePrivate", "PropertyName") - -package pers.shawxingkwok.androidutil.view - -import android.os.Parcelable -import android.util.SparseArray -import androidx.fragment.app.Fragment -import kotlinx.parcelize.Parcelize -import pers.shawxingkwok.mvb.android.save -import pers.shawxingkwok.mvb.android.transform - -class SaveWithParcelableComponents { - class MyFragment : Fragment(){ - @Parcelize - data class User(val id: Long, val name: String): Parcelable - - /** - * `KClass`(`User::class` in this case) could be automatically - * recognized as the parcelable component, if the ultimately saved type is `Parcelable` - * or Array. - */ - var user by save{ User(1, "Apollo") } - var users by save{ emptyArray() } - - // pass `User::class` when ultimately saved in List/SparseArray - val _users by save(User::class){ mutableListOf() } - val userGroups by save(User::class){ mutableListOf>() } - val __users by save(User::class){ SparseArray() } - val _userGroups by save(User::class){ SparseArray>() } - - // `ultimately` means saved types change with transform. - } -} \ No newline at end of file diff --git a/restoretest/build.gradle b/restoretest/build.gradle index c28833f..f93129e 100644 --- a/restoretest/build.gradle +++ b/restoretest/build.gradle @@ -57,5 +57,6 @@ dependencies { dependencies { implementation(project(":api")) +// implementation("io.github.shawxingkwok:mvb-android:1.0.5") implementation(libs.bundles.shawxing) } \ No newline at end of file diff --git a/restoretest/src/androidTest/java/pers/shawxingkwok/restoretest/ExampleInstrumentedTest.kt b/restoretest/src/androidTest/java/pers/shawxingkwok/restoretest/ExampleInstrumentedTest.kt index 02d4c45..ddd71a0 100644 --- a/restoretest/src/androidTest/java/pers/shawxingkwok/restoretest/ExampleInstrumentedTest.kt +++ b/restoretest/src/androidTest/java/pers/shawxingkwok/restoretest/ExampleInstrumentedTest.kt @@ -1,13 +1,9 @@ package pers.shawxingkwok.restoretest -import androidx.test.platform.app.InstrumentationRegistry import androidx.test.ext.junit.runners.AndroidJUnit4 - import org.junit.Test import org.junit.runner.RunWith -import org.junit.Assert.* - /** * Instrumented test, which will execute on an Android device. * @@ -17,8 +13,5 @@ import org.junit.Assert.* class ExampleInstrumentedTest { @Test fun useAppContext() { - // Context of the app under test. - val appContext = InstrumentationRegistry.getInstrumentation().targetContext - assertEquals("pers.shawxingkwok.restoretest", appContext.packageName) } } \ No newline at end of file diff --git a/restoretest/src/main/java/pers/shawxingkwok/restoretest/MainActivity.kt b/restoretest/src/main/java/pers/shawxingkwok/restoretest/MainActivity.kt index 991564b..76b5343 100644 --- a/restoretest/src/main/java/pers/shawxingkwok/restoretest/MainActivity.kt +++ b/restoretest/src/main/java/pers/shawxingkwok/restoretest/MainActivity.kt @@ -1,3 +1,5 @@ +@file:Suppress("MemberVisibilityCanBePrivate") + package pers.shawxingkwok.restoretest import android.os.Bundle @@ -10,17 +12,21 @@ import pers.shawxingkwok.mvb.android.saveMutableSharedFlow import pers.shawxingkwok.mvb.android.saveMutableStateFlow import java.math.BigDecimal +inline fun Any?.isArray() = + this is Array<*> && javaClass.componentType == T::class.java + class MainActivity : ComponentActivity() { - private val sharedFlow by saveMutableSharedFlow<_, Array>( - replay = 3, - parcelableComponent = P::class - ) + init { + assert(arrayOf(P(0)).isArray

()) + } - private val _sharedFlow by saveMutableSharedFlow<_, Array

>( + private val sharedFlow by saveMutableSharedFlow<_, List

>( replay = 3, parcelableComponent = P::class ) + private val _sharedFlow by saveMutableSharedFlow<_, Array

>(replay = 3) + private val stateFlow by saveMutableStateFlow { 0 } val liveData by saveMutableLiveData { 0 } @@ -32,6 +38,13 @@ class MainActivity : ComponentActivity() { val ints by save { intArrayOf(0) } + val ps by save { arrayOf(P(0)) } + val _ps by save(P::class) { listOf(arrayOf(P(0))) } + + val qs by save { arrayOf(Q1(), Q2()) } + val _qs by save { listOf(arrayOf(Q1(), Q2())) } + + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -40,23 +53,31 @@ class MainActivity : ComponentActivity() { assert(emptyLiveData.value == null) liveData.value = 1 nullableLiveData.value = null - sharedFlow.tryEmit(arrayOf(P(2))) - sharedFlow.tryEmit(arrayOf("")) - _sharedFlow.tryEmit(arrayOf(P(2))) - _sharedFlow.tryEmit(arrayOf(P(3))) + sharedFlow.tryEmit(listOf(P(0))) + _sharedFlow.tryEmit(arrayOf()) sparseArray.append(0, P(0)) number += BigDecimal(1) ints[0]++ + ps[0].i++ + _ps[0][0].i++ + qs[0].i++ + _qs.first()[0].i++ }else { + assert(stateFlow.value == 1) assert(emptyLiveData.value == null) assert(liveData.value == 1) assert(nullableLiveData.value == null) - assert(sharedFlow.replayCache.first().first() is P) - assert(_sharedFlow.replayCache.first().first().i == 2) + assert(sharedFlow.replayCache.first().first().i == 0) + assert(_sharedFlow.replayCache.first().isArray

()) assert(sparseArray.valueAt(0) == P(0)) assert(number.toInt() == 1) assert(ints.first() == 1) + assert(ps.isArray

()) + assert(qs.isArray()) + assert(_qs.first().isArray()) + // This parcelable bug should be fixed by the authority + KLog.d(_ps.first().isArray()) KLog.d("done") } } diff --git a/restoretest/src/main/java/pers/shawxingkwok/restoretest/P.kt b/restoretest/src/main/java/pers/shawxingkwok/restoretest/P.kt index 6be0923..0a83a60 100644 --- a/restoretest/src/main/java/pers/shawxingkwok/restoretest/P.kt +++ b/restoretest/src/main/java/pers/shawxingkwok/restoretest/P.kt @@ -2,9 +2,8 @@ package pers.shawxingkwok.restoretest import android.os.Parcel import android.os.Parcelable -import pers.shawxingkwok.androidutil.KLog -data class P(val i: Int) : Parcelable { +data class P(var i: Int) : Parcelable { override fun describeContents(): Int { return 0 } diff --git a/restoretest/src/main/java/pers/shawxingkwok/restoretest/Q.kt b/restoretest/src/main/java/pers/shawxingkwok/restoretest/Q.kt new file mode 100644 index 0000000..3383b56 --- /dev/null +++ b/restoretest/src/main/java/pers/shawxingkwok/restoretest/Q.kt @@ -0,0 +1,10 @@ +package pers.shawxingkwok.restoretest + +import java.io.Serializable + +interface Q : Serializable{ + var i: Int +} +class Q1(override var i: Int = 0) : Q + +class Q2(override var i: Int = 0) : Q \ No newline at end of file