What is causing this Error: com.android.tools.r8.internal.nc: Sealed classes are not supported as program classes

Viewed 58

I'm learning Jetpack Compose, and while learning I ran into some problems that I don't know how to solve. Below is my development environment, code and compiled result.

Environment:

  • Android Studio Chipmunk | 2021.2.1 Patch 2Build
  • Kotlin version: 1.7.10
  • Android Gradle version: 7.2.2
  • JDK version: 17.0.4
  • CompileSdk: 33

Code:

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            DemoTheme {
                Surface(
                    modifier = Modifier.fillMaxSize(),
                    color = MaterialTheme.colorScheme.background
                ) {
                    Greeting()
                }
            }
        }
    }
}
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun Greeting(
    viewModel: GreetingViewModel = remember {
        GreetingViewModel()
    }
) {
    val uiState = viewModel.uiState.collectAsState().value
    Column(
        modifier = Modifier
            .fillMaxWidth()
            .padding(32.dp)
    ) {
        TextField(value = uiState.name, onValueChange = {

            viewModel.handleAction(
                GreetingViewModel.UiAction.NameChanged(it)
            )
        })
        Text(text = "Hello ${uiState.name}!")
    }
}
class GreetingViewModel {
    data class UiState(val name: String)

    private val _uiState = MutableStateFlow(UiState(name = ""))
    val uiState: StateFlow<UiState> = _uiState.asStateFlow()

    sealed class UiAction {
        class NameChanged(val name: String) : UiAction()
    }

    fun handleAction(action: UiAction) {
        when (action) {
            is UiAction.NameChanged -> {
                _uiState.value = uiState.value.copy(
                    name = action.name
                )
            }
        }
    }
}

Result:

GreetingViewModel$UiAcion.class: Decompiled.class file, bytecode version:61.0(Java 17)

Waring: One or more classes has class file version >= 56 which is not officially supported.

Error: com.android.tools.r8.internal.nc: Sealed classes are not supported as program classes
2 Answers

In Kotlin 1.0, the sealed functionality is rather restricted. For instance, all the subclasses must be nested, and a subclass can’t be made a data class ( data classes are covered later in this chapter). Kotlin 1.1 relaxes the restrictions and lets you define subclasses of sealed classes anywhere in the same file. In the given example, it is not allowed up until now. May be, in later release versions, they will relax this restriction. However, you can do this:

class SomeActivity {
    sealed class Expr {
        data class Const(val number: Double) : Expr()
        data class Sum(val e1: Expr, val e2: Expr) : Expr()
        object NotANumber : Expr()
    }
}

Sealed classes are not fully supported in the D8 and R8 compilers (the compilers producing your Sealed classes are not supported as program classes error). Fully supporting sealed classes is tracked in https://issuetracker.google.com/227160052. The D8 support will be present in Android Studio Electric Eel, currently in preview whereas the R8 support will no be there until a later version.

Related