user1866731
user1866731

Reputation: 499

java.lang.RuntimeException: Unknown animation name: x

Since i enable proguard im starting have this crash(below) when i press an option on DrawerLayout. Navigation is made with navigation component and it is using default animation. I understand i must put rule on proguard, but whick rule and more important why?

E/AnimationUtils: loadAnimation: resourceName = mypackagename:animator/nav_default_exit_anim E/AndroidRuntime: FATAL EXCEPTION: main Process: mypackagename, PID: 22537 java.lang.RuntimeException: Unknown animation name: x at android.view.animation.AnimationUtils.createAnimationFromXml(AnimationUtils.java:214) at android.view.animation.AnimationUtils.createAnimationFromXml(AnimationUtils.java:179) at android.view.animation.AnimationUtils.loadAnimation(AnimationUtils.java:143) at l.i.b.b.A(:2)

Upvotes: 4

Views: 1609

Answers (5)

Dewey Reed
Dewey Reed

Reputation: 4956

The related issue is Resource shrinker - keep used constants from R class (unless entire R is kept).

My solution is :

Original code that crashes:

fun NavOptions.Builder.withDefaultAnimation(): NavOptions.Builder {
    setEnterAnim(R.animator.nav_default_enter_anim)
    setExitAnim(R.animator.nav_default_exit_anim)
    setPopEnterAnim(R.animator.nav_default_pop_enter_anim)
    setPopExitAnim(R.animator.nav_default_pop_exit_anim)
    return this
}

After I use the code below somewhere in the project, it doesn't crash anymore. Weird.

navOptions {
    anim {
        enter = R.animator.nav_default_enter_anim
        exit = R.animator.nav_default_exit_anim
        popEnter = R.animator.nav_default_pop_enter_anim
        popExit = R.animator.nav_default_pop_exit_anim
    }
}

Upvotes: 0

Branislav Zlatkovic
Branislav Zlatkovic

Reputation: 41

Had the very same issue, what worked for me is to replace all @anim/ with @animator/

my diff that saved the day

Upvotes: 0

Alberto M
Alberto M

Reputation: 1760

I found the answer on this other question. The problem basically was proguard that randomly decided to stop loading the resources.

Fix for me was:

-keepclassmembers class **.R$* {
       public static <fields>; 
}

Upvotes: 6

kgbier
kgbier

Reputation: 103

I recently upgraded to fragment:fragment-ktx:1.3.2 and am seeing this crash as well whenever I navigate using BottomNavigation.

It seems these animations are referenced in Jetpack Navigation (NavigationUI.onNavDestinationSelected), and are being optimised by shrinkResources.

R.anim.nav_default_enter_anim
R.anim.nav_default_exit_anim
R.anim.nav_default_pop_enter_anim
R.anim.nav_default_pop_exit_anim
R.animator.nav_default_enter_anim
R.animator.nav_default_exit_anim
R.animator.nav_default_pop_enter_anim
R.animator.nav_default_pop_exit_anim

I tried to retain these using:

<resources xmlns:tools="http://schemas.android.com/tools"
       tools:keep="@anim/nav_default*"/>

but that didn't work.

So I opted for referencing them in code.

Successful workaround:

@Keep
fun _keep() = listOf(
    R.anim.nav_default_enter_anim,
    R.anim.nav_default_exit_anim,
    R.anim.nav_default_pop_enter_anim,
    R.anim.nav_default_pop_exit_anim,

    R.animator.nav_default_enter_anim,
    R.animator.nav_default_exit_anim,
    R.animator.nav_default_pop_enter_anim,
    R.animator.nav_default_pop_exit_anim,
)

I had difficulty reproducing this in a sample project, so am unable to work out what causes this exactly.

Upvotes: 1

Ihor Levkivskyi
Ihor Levkivskyi

Reputation: 391

I had the same issue with BottomNavigationView in release version. I think for DrawerLayout key should be the same.

Issue was with this method:

itemMenu.onNavDestinationSelected(navController)

Problem with obfuscate name of animation files in Navigation Component

enter image description here

Solution: I just override(a bit hardcoded;), but it works fine:

    bottom_nav.setOnNavigationItemSelectedListener {
        val navBuilder = NavOptions.Builder()
            .setLaunchSingleTop(true)
        if (itemMenu.order and Menu.CATEGORY_SECONDARY == 0) {
            navBuilder.setPopUpTo(
                findStartDestination(navController.graph)?.id ?: R.id.mainFragment, false
            )
        }
        val options = navBuilder.build()
        navController.navigate(
            if (itemMenu.itemId == R.id.subMainFragment) provideMainDestination() else itemMenu.itemId,
            null,
            options
        )
        true
    }

fun findStartDestination(graph: NavGraph): NavDestination? {
    var startDestination: NavDestination? = graph
    while (startDestination is NavGraph) {
        val parent = startDestination
        startDestination = parent.findNode(parent.startDestination)
    }
    return startDestination
}

Upvotes: 0

Related Questions