rFor a while now, I have been used to the fact that sometimes the IDE (Android Studio Koala 2024.1.1) marks in red the navigation directions and yet compiles the app, which runs fine. Example:
Note that this has the inconvenient that you get used to ignore the red marks and need to compile to find out the real coding errors.
Today however, I added a new navigation link which this time generates a runtime exception:
Here the navigation action is generated by a click on a Snackbar action, after a room database query:
Again, the code is compiled successfully in spite of the red marks but now generates a runtime exception.
Here the code:
private fun actionEditOnClickListener(): View.OnClickListener = View.OnClickListener{ view ->
val action: FragmentAddMotDirections.AddMotToEditMot = FragmentAddMotDirections.addMotToEditMot()
val viewModel = ViewModelProvider(requireActivity())[SharedViewModel::class.java]
viewModel.orthoAlt(motEnCours, defMotAEditer)
viewModel.getOrthoAlt().observe(viewLifecycleOwner) { ort ->
ort?.let {
action.mot = motEnCours
if (it.isNotEmpty()){
action.orthoAlt = "= " + it.joinToString (" ")
}
action.defId = defMotAEditer
Navigation.findNavController(view).navigate(action)
}
}
}
Can someone tell me if the problems is linked to the navigation class generation or is there something else in the snackbar code that does not fit ?
I know there is a plenty of posts asking about navigation class generation and I tried most of the suggested answers without succes.
Here is the project gradle:
buildscript {
dependencies {
classpath("androidx.navigation:navigation-safe-args-gradle-plugin:2.7.7")
}
}
plugins {
id("com.android.application") version "8.5.1" apply false
id("org.jetbrains.kotlin.android") version "1.9.21" apply false
id("com.google.devtools.ksp") version "1.9.21-1.0.15" apply false
}
app gradle:
plugins {
id("com.android.application")
id("org.jetbrains.kotlin.android")
id("com.google.devtools.ksp")
id ("androidx.navigation.safeargs")
}
ksp {
arg("room.schemaLocation", "$projectDir/schemas")
}
android {
lint {
baseline = file("lint-baseline.xml")
}
buildFeatures {
viewBinding = true
}
namespace = "com.simonwintz.millemots"
compileSdk = 34
defaultConfig {
applicationId = "com.simonwintz.millemots"
minSdk = 26
//noinspection OldTargetApi
targetSdk = 34
versionCode = 15
versionName = "2.5"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
isMinifyEnabled = false
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
kotlinOptions {
jvmTarget = "17"
}
}
dependencies {
implementation("androidx.core:core-ktx:1.13.1")
implementation("androidx.appcompat:appcompat:1.7.0")
implementation("com.google.android.material:material:1.12.0")
implementation("androidx.constraintlayout:constraintlayout:2.1.4")
implementation ("androidx.navigation:navigation-fragment-ktx:2.7.7")
implementation ("androidx.navigation:navigation-ui-ktx:2.7.7")
implementation("androidx.legacy:legacy-support-v4:1.0.0")
testImplementation("junit:junit:4.13.2")
implementation ("androidx.room:room-runtime:2.6.1")
implementation ("androidx.fragment:fragment-ktx:1.8.1")
implementation ("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.1")
implementation ("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.8.1")
ksp ("androidx.room:room-compiler:2.6.1")
androidTestImplementation("androidx.test.ext:junit:1.2.1")
androidTestImplementation("androidx.test.espresso:espresso-core:3.6.1")
}
And here the navigation graph:
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/navigation_graph"
app:startDestination="@id/fragmentBaseMots">
<fragment
android:id="@+id/fragmentBaseMots"
android:name="com.simonwintz.millemots.FragmentBaseMots"
android:label="fragment_base_mots"
tools:layout="@layout/fragment_base_mots" >
<action
android:id="@+id/baseMotsToJeu"
app:destination="@id/fragmentJeu" />
<action
android:id="@+id/baseMotsToRefill"
app:destination="@id/fragmentRefill" />
<action
android:id="@+id/baseMotsToPref"
app:destination="@id/fragmentPref" />
<action
android:id="@+id/baseMotsToAddMot"
app:destination="@id/fragmentAddMot" />
<action
android:id="@+id/baseMotsToEditMot"
app:destination="@id/fragmentEditMot" />
<action
android:id="@+id/baseMotsToShare"
app:destination="@id/fragmentShare" />
<action
android:id="@+id/baseMotsToFiltres"
app:destination="@id/fragmentFiltres" />
</fragment>
<fragment
android:id="@+id/fragmentJeu"
android:name="com.simonwintz.millemots.FragmentJeu"
android:label="fragment_jeu"
tools:layout="@layout/fragment_jeu" >
<argument
android:name="totalMots"
app:argType="string"
android:defaultValue='""' />
<argument
android:name="totalCoups"
app:argType="string"
android:defaultValue='""' />
<argument
android:name="totalActifs"
app:argType="string"
android:defaultValue='""' />
<argument
android:name="tauxMoyen"
app:argType="string"
android:defaultValue='""' />
</fragment>
<fragment
android:id="@+id/fragmentRefill"
android:name="com.simonwintz.millemots.FragmentRefill"
android:label="FragmentRefill"
tools:layout="@layout/fragment_refill">
<argument
android:name="message"
app:argType="string"
android:defaultValue="No message!" />
<argument
android:name="tauxErreur"
app:argType="float"
android:defaultValue="0.0" />
</fragment>
<fragment
android:id="@+id/fragmentPref"
android:name="com.simonwintz.millemots.FragmentPref"
android:label="fragment_pref"
tools:layout="@layout/fragment_pref">
<argument
android:name="Message"
app:argType="string"
android:defaultValue='"No message!"' />
<argument
android:name="totalBase"
app:argType="integer"
android:defaultValue="0" />
</fragment>
<fragment
android:id="@+id/fragmentHelp"
android:name="com.simonwintz.millemots.FragmentHelp"
tools:layout="@layout/fragment_help"
android:label="FragmentHelp" >
<argument
android:name="dispSwitch"
app:argType="boolean"
android:defaultValue="true" />
</fragment>
<action android:id="@+id/moveToHelp"
app:destination="@+id/fragmentHelp"/>
<fragment
android:id="@+id/fragmentAddMot"
android:name="com.simonwintz.millemots.FragmentAddMot"
android:label="FragmentAddMot"
tools:layout="@layout/fragment_add_mot" >
<argument
android:name="mot"
app:argType="string" />
<action
android:id="@+id/addMotToEditMot"
app:destination="@id/fragmentEditMot" />
</fragment>
<fragment
android:id="@+id/fragmentEditMot"
android:name="com.simonwintz.millemots.FragmentEditMot"
android:label="FragmentEditMot"
tools:layout="@layout/fragment_edit_mot" >
<argument
android:name="mot"
app:argType="string"
android:defaultValue='""' />
<argument
android:name="orthoAlt"
app:argType="string"
android:defaultValue='""' />
<argument
android:name="defId"
app:argType="long"
android:defaultValue="0L" />
</fragment>
<fragment
android:id="@+id/fragmentShare"
android:name="com.simonwintz.millemots.FragmentShare"
android:label="FragmentShare"
tools:layout="@layout/fragment_share" >
<argument
android:name="message"
app:argType="string"
android:defaultValue='"No message!"' />
</fragment>
<fragment
android:id="@+id/fragmentFiltres"
android:name="com.simonwintz.millemots.FragmentFiltres"
android:label="FragmentFiltres"
tools:layout="@layout/fragment_filtres" >
<action
android:id="@+id/filtresToJeu"
app:destination="@id/fragmentJeu" />
<argument
android:name="totalMots"
app:argType="string"
android:defaultValue='""' />
<argument
android:name="totalCoups"
app:argType="string"
android:defaultValue='""' />
<argument
android:name="totalActifs"
app:argType="string"
android:defaultValue='""' />
<argument
android:name="tauxMoyen"
app:argType="string"
android:defaultValue='""' />
<action
android:id="@+id/filtresToAddMot"
app:destination="@id/fragmentAddMot" />
</fragment>
</navigation>
2
Answers
This issue has gone by itself, probably after an Xcode update, I did not notice which one.
U use kotlin so you plugin is id ("androidx.navigation.safeargs.kotlin") not
id ("androidx.navigation.safeargs")