web-dev-qa-db-ja.com

Androidナビゲーションコンポーネントでランタイム例外を引き起こすProguard

NavigationComponent(Android.Arch.navigation:navigation-fragment-ktx:1.0.0-alpha01)をターゲットにプロジェクトに統合し、sdkを27にコンパイルしてからプロガードを使用すると、このクラッシュが発生します

    2018-05-16 12:13:14.044 24573-24573/com.mypackage.myapp.x E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.mypackage.myapp.x, PID: 24573
    Java.lang.RuntimeException: Unable to start activity ComponentInfo{com.mypackage.myapp.x/com.mypackage.myapp.MainActivity}: Android.view.InflateException: Binary XML file line #16: Binary XML file line #16: Error inflating class fragment
        at Android.app.ActivityThread.performLaunchActivity(ActivityThread.Java:2925)
        at Android.app.ActivityThread.handleLaunchActivity(ActivityThread.Java:3060)
        at Android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.Java:78)
        at Android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.Java:110)
        at Android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.Java:70)
        at Android.app.ActivityThread$H.handleMessage(ActivityThread.Java:1800)
        at Android.os.Handler.dispatchMessage(Handler.Java:106)
        at Android.os.Looper.loop(Looper.Java:164)
        at Android.app.ActivityThread.main(ActivityThread.Java:6649)
        at Java.lang.reflect.Method.invoke(Native Method)
        at com.Android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.Java:493)
        at com.Android.internal.os.ZygoteInit.main(ZygoteInit.Java:826)
     Caused by: Android.view.InflateException: Binary XML file line #16: Binary XML file line #16: Error inflating class fragment
     Caused by: Android.view.InflateException: Binary XML file line #16: Error inflating class fragment
     Caused by: Java.lang.RuntimeException: Exception inflating com.mypackage.myapp.x:navigation/nav_graph line 7
        at androidx.navigation.j.a(Unknown Source:124)
        at androidx.navigation.d.a(Unknown Source:4)
        at androidx.navigation.fragment.NavHostFragment.a(Unknown Source:88)
        at Android.support.v4.app.Fragment.l(Unknown Source:15)
        at Android.support.v4.app.m.a(Unknown Source:369)
        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.d.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.rInflate(LayoutInflater.Java:866)
        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.AppCompatDelegateImplV9.b(Unknown Source:23)
        at Android.support.v7.app.d.setContentView(Unknown Source:4)
        at com.mypackage.myapp.MainActivity.onCreate(Unknown Source:12)
        at Android.app.Activity.performCreate(Activity.Java:7130)
        at Android.app.Activity.performCreate(Activity.Java:7121)
        at Android.app.Instrumentation.callActivityOnCreate(Instrumentation.Java:1262)
        at Android.app.ActivityThread.performLaunchActivity(ActivityThread.Java:2905)
        at Android.app.ActivityThread.handleLaunchActivity(ActivityThread.Java:3060)
        at Android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.Java:78)
        at Android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.Java:110)
        at Android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.Java:70)
        at Android.app.ActivityThread$H.handleMessage(ActivityThread.Java:1800)
        at Android.os.Handler.dispatchMessage(Handler.Java:106)
        at Android.os.Looper.loop(Looper.Java:164)
        at Android.app.ActivityThread.main(ActivityThread.Java:6649)
        at Java.lang.reflect.Method.invoke(Native Method)
    2018-05-16 12:13:14.044 24573-24573/com.mypackage.myapp.x E/AndroidRuntime:     at com.Android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.Java:493)
        at com.Android.internal.os.ZygoteInit.main(ZygoteInit.Java:826)
     Caused by: Java.lang.RuntimeException: Java.lang.ClassNotFoundException: com.mypackage.myapp.fragments.MainFragment
        at androidx.navigation.fragment.b$a.a(Unknown Source:58)
        at androidx.navigation.fragment.b$a.a(Unknown Source:19)
        at androidx.navigation.j.a(Unknown Source:16)
        at androidx.navigation.j.a(Unknown Source:133)
        at androidx.navigation.j.a(Unknown Source:31)
            ... 38 more
     Caused by: Java.lang.ClassNotFoundException: com.mypackage.myapp.fragments.MainFragment
        at Java.lang.Class.classForName(Native Method)
        at Java.lang.Class.forName(Class.Java:453)
        at androidx.navigation.fragment.b$a.a(Unknown Source:45)
            ... 42 more
     Caused by: Java.lang.ClassNotFoundException: Didn't find class "com.mypackage.myapp.fragments.MainFragment" on path: DexPathList[[Zip file "/system/framework/org.Apache.http.legacy.boot.jar", Zip file "/data/app/com.mypackage.myapp.x-ysts055HQTtJTv5J2uej3g==/base.apk"],nativeLibraryDirectories=[/data/app/com.mypackage.myapp.x-ysts055HQTtJTv5J2uej3g==/lib/x86, /system/lib]]
        at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.Java:125)
        at Java.lang.ClassLoader.loadClass(ClassLoader.Java:379)
        at Java.lang.ClassLoader.loadClass(ClassLoader.Java:312)
            ... 45 more

AAPTがナビゲーションコンポーネントの保持ルールをまだ作成していないためでしょうか?

13
Kayvan N

ProguardとR8はライブラリクラスのすべての子を保持する必要があることを知っていますが、この場合、フラグメントクラスが欠落しているようです。この保持ルールは私の問題を解決しましたが、技術的にはこのルールはまったく必要ありません!

-keep class * extends Android.support.v4.app.Fragment{}

AndroidXを使用している場合は、次のルールを使用します:-keep class * extends androidx.fragment.app.Fragment{}

また、ナビゲーションXMLでargTypeを使用する場合は、現在、そのルールも必要です。例:-keep class com.example.model.MyModel

13
Kayvan N

同じ問題に直面しました。上記の答えは私に調査する正しい方向を与えました。 navigation docs によると

-keep class * extends Android.support.v4.app.Fragment{} <-this is not needed 

あなたがする必要があるのは、安全な引数を介して渡されるデータクラスの名前を保持することです

-keepnames class com.your.package.models.*
2