0

I have some data classes for my Android app, and would like to play around with them in a scratch file (or something similar). As long as they don't use the Android Platform API, I can use them in a scratch file in Android Studio. For example, class definition:

@Serializable
class Day(val epochDays: Int) { }

and scratch file using classpath MyApp.app.main:

Day(3)

However, I want some of my data classes to be usable with Compose's rememberSaveable, so they need to implement android.os.Parcelable. Easy enough:

@Serializable
@Parcelize
class TaskId(val string: String) : Parcelable { }

But now, I can't use this in my scratch file:

TaskId("test")

because Parcelable is part of the Android Platform API. It gives me this error:

Exception in thread "main" java.lang.NoClassDefFoundError: android/os/Parcelable
  at java.base/java.lang.ClassLoader.defineClass1(Native Method)
  at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1012)
  at java.base/java.security.SecureClassLoader.defineClass(SecureClassLoader.java:150)
  at java.base/jdk.internal.loader.BuiltinClassLoader.defineClass(BuiltinClassLoader.java:862)
  at java.base/jdk.internal.loader.BuiltinClassLoader.findClassOnClassPathOrNull(BuiltinClassLoader.java:760)
  at java.base/jdk.internal.loader.BuiltinClassLoader.loadClassOrNull(BuiltinClassLoader.java:681)
  at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:639)
  at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
  at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520)
  at org.jetbrains.kotlin.idea.scratch.generated.ScratchFileRunnerGenerated$ScratchFileRunnerGenerated.generated_get_instance_res2(tmp.kt:11)
  at org.jetbrains.kotlin.idea.scratch.generated.ScratchFileRunnerGenerated.main(tmp.kt:22)
Caused by: java.lang.ClassNotFoundException: android.os.Parcelable
  at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641)
  at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
  at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520)
  ... 11 more

I could refactor my code base to support scratch files, but scratch files are not artifacts, so I don't want to make my code convoluted just for them. And besides, Parcelable is just an interface. Is there some way I could tell Android Studio to swap in an alternate android.os.Parcelable definition for scratch files, similar to whatever Robolectric does?

I have tried some things which didn't work:

  • I tried putting my scratch file in the package android.os, then defining an empty interface Parcelable so that it would be android.os.Parcelable:

    package android.os
    import org.example.TaskId
    interface Parcelable
    println(TaskId::class)
    

    but the error appears identical: it still "can't" find android/os/Parcelable.

  • I tried setting the classpath to MyApp.app.unitTest (or even MyApp.app.androidTest) instead of MyApp.app.unitTest. When I do that, it can't even find TaskId to begin with!

1
  • For anyone looking into scratch files in Android Studio at the moment, I found I needed to use the secret hand signal (Ctrl+Alt+Shift+Ins) and K1 mode (youtrack.jetbrains.com/issue/KTIJ-34604) Commented Jul 18 at 16:08

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.