Компонент Android Architecture Navigation и результаты Proguard в java.lang.ClassNotFoundException

При запуске сборки с поддержкой proguard с новым компонентом навигации Android мой класс фрагментов не может быть найден. Я получаю эту трассировку стека:

E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.myapppackage.path, PID: 24334
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.myapppackage.path/com.myapppackage.path.MainActivity}: android.view.InflateException: Binary XML file line #10: Binary XML file line #10: Error inflating class fragment
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2778)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2856)
    at android.app.ActivityThread.-wrap11(Unknown Source:0)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1589)
    at android.os.Handler.dispatchMessage(Handler.java:106)
    at android.os.Looper.loop(Looper.java:164)
    at android.app.ActivityThread.main(ActivityThread.java:6494)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
 Caused by: android.view.InflateException: Binary XML file line #10: Binary XML file line #10: Error inflating class fragment
 Caused by: android.view.InflateException: Binary XML file line #10: Error inflating class fragment
 Caused by: java.lang.RuntimeException: Exception inflating com.myapppackage.path:navigation/nav_graph line 7
    at androidx.navigation.h.a(Unknown Source:124)
    at androidx.navigation.c.a(Unknown Source:4)
    at androidx.navigation.fragment.NavHostFragment.a(Unknown Source:88)
    at android.support.v4.app.g.k(Unknown Source:15)
    at android.support.v4.app.m.a(Unknown Source:382)
    at android.support.v4.app.m.b(Unknown Source:7)
    at android.support.v4.app.m.a(Unknown Source:74)
    at android.support.v4.app.m.onCreateView(Unknown Source:216)
    at android.support.v4.app.j.a(Unknown Source:4)
    at android.support.v4.app.h.a(Unknown Source:2)
    at android.support.v4.app.e.onCreateView(Unknown Source:0)
    at android.support.v4.app.h.onCreateView(Unknown Source:0)
    at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:780)
    at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:730)
    at android.view.LayoutInflater.rInflate(LayoutInflater.java:863)
    at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:824)
    at android.view.LayoutInflater.inflate(LayoutInflater.java:515)
    at android.view.LayoutInflater.inflate(LayoutInflater.java:423)
    at android.view.LayoutInflater.inflate(LayoutInflater.java:374)
    at android.support.v7.app.j.b(Unknown Source:23)
    at android.support.v7.app.c.setContentView(Unknown Source:4)
    at com.myapppackage.path.MainActivity.onCreate(Unknown Source:6)
    at android.app.Activity.performCreate(Activity.java:6999)
    at android.app.Activity.performCreate(Activity.java:6990)
    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1214)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2731)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2856)
    at android.app.ActivityThread.-wrap11(Unknown Source:0)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1589)
    at android.os.Handler.dispatchMessage(Handler.java:106)
    at android.os.Looper.loop(Looper.java:164)
    at android.app.ActivityThread.main(ActivityThread.java:6494)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
 Caused by: java.lang.RuntimeException: java.lang.ClassNotFoundException: com.myapppackage.path.ui.start.StartFragment
    at androidx.navigation.fragment.a$a.a(Unknown Source:58)
    at androidx.navigation.fragment.a$a.a(Unknown Source:19)
    at androidx.navigation.h.a(Unknown Source:16)
    at androidx.navigation.h.a(Unknown Source:133)
    at androidx.navigation.h.a(Unknown Source:31)
    at androidx.navigation.c.a(Unknown Source:4) 
    at androidx.navigation.fragment.NavHostFragment.a(Unknown Source:88) 
    at android.support.v4.app.g.k(Unknown Source:15) 
    at android.support.v4.app.m.a(Unknown Source:382) 
    at android.support.v4.app.m.b(Unknown Source:7) 
    at android.support.v4.app.m.a(Unknown Source:74) 
    at android.support.v4.app.m.onCreateView(Unknown Source:216) 
    at android.support.v4.app.j.a(Unknown Source:4) 
    at android.support.v4.app.h.a(Unknown Source:2) 
    at android.support.v4.app.e.onCreateView(Unknown Source:0) 
    at android.support.v4.app.h.onCreateView(Unknown Source:0) 
    at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:780) 
    at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:730) 
    at android.view.LayoutInflater.rInflate(LayoutInflater.java:863) 
    at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:824) 
    at android.view.LayoutInflater.inflate(LayoutInflater.java:515) 
    at android.view.LayoutInflater.inflate(LayoutInflater.java:423) 
    at android.view.LayoutInflater.inflate(LayoutInflater.java:374) 
    at android.support.v7.app.j.b(Unknown Source:23) 
    at android.support.v7.app.c.setContentView(Unknown Source:4) 
    at com.myapppackage.path.MainActivity.onCreate(Unknown Source:6) 
    at android.app.Activity.performCreate(Activity.java:6999) 
    at android.app.Activity.performCreate(Activity.java:6990) 
    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1214) 
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2731) 
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2856) 
    at android.app.ActivityThread.-wrap11(Unknown Source:0) 
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1589) 
    at android.os.Handler.dispatchMessage(Handler.java:106) 
    at android.os.Looper.loop(Looper.java:164) 
    at android.app.ActivityThread.main(ActivityThread.java:6494) 
    at java.lang.reflect.Method.invoke(Native Method) 
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807) 
 Caused by: java.lang.ClassNotFoundException: com.myapppackage.path.ui.start.StartFragment
    at java.lang.Class.classForName(Native Method)
    at java.lang.Class.forName(Class.java:453)
E/AndroidRuntime:     at androidx.navigation.fragment.a$a.a(Unknown Source:45)
            ... 38 more
     Caused by: java.lang.ClassNotFoundException: Didn't find class "com.myapppackage.path.ui.start.StartFragment" on path: DexPathList[[zip file "/data/app/com.myapppackage.path-yqk9eOoCoeyT3xg78oYcxg==/base.apk"],nativeLibraryDirectories=[/data/app/com.myapppackage.path-yqk9eOoCoeyT3xg78oYcxg==/lib/arm64, /system/lib64, /vendor/lib64]]
        at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:125)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:379)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
            ... 41 more

Он говорит, что не может найти класс фрагмента, который определен в моем файле nav_graph.xml:

Caused by: java.lang.RuntimeException: java.lang.ClassNotFoundException: com.myapppackage.path.ui.start.StartFragment

My nav_graph.xml:

<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    app:startDestination="@id/start">

    <fragment
        android:id="@+id/start"
        android:name="com.myapppackage.path.ui.start.StartFragment"
        android:label="start_fragment"
        tools:layout="@layout/start_fragment" />
</navigation>

Как видите, имя фрагмента задано в xml, этот путь кажется недействительным после запуска через proguard.

Мой единственный обходной путь до сих пор заключается в том, чтобы определить каждый из моих путей к классам фрагментов как -keepnames в моем файле proguard-rules.pro. Например:

-keepnames class com.myapppackage.path.ui.start.StartFragment

После этого обфусцированный компилятор работает без сбоев.

Хотя я не уверен, что это правильно, я делаю что-то не так? Как мы можем использовать новый компонент архитектуры навигации с нашими обфусцированными сборками, не определяя правило для каждого фрагмента в правилах proguard?

Я понимаю, что эта проблема может быть проблемой только сейчас, потому что компонент навигационного фрагмента все еще находится в альфа-версии.


person jesobremonte    schedule 19.05.2018    source источник
comment
Я думаю, что в этом ответе есть решение вашей проблемы.   -  person Ivan Kušt    schedule 24.05.2018