# JNI reaches these by name. R8 renames by default, so without these rules a # release build resolves nothing: GetMethodID("onOutput", ...) returns NULL, # raises NoSuchMethodError, and the next JNI call aborts the process with # NoSuchMethodError: no non-static method "Lp0;.onOutput(Ljava/lang/String;)V" # Debug builds do not minify, so this only ever appears in release. # The plugin object holds the native method declarations and is looked up from # C by its fully qualified name (Java_com_novoyuuparosk_iperf3gui_IperfRunner_*). -keep class com.novoyuuparosk.iperf3gui.IperfRunner { *; } # The callback interface and everything implementing it: iperf_jni.c resolves # onOutput/onError/onComplete by name on the concrete object's class, so the # implementors' method names must survive too, not just the interface's. -keep interface com.novoyuuparosk.iperf3gui.IperfRunner$IperfCallback { *; } -keep class * implements com.novoyuuparosk.iperf3gui.IperfRunner$IperfCallback { *; } # Belt and braces for any future native method: keep the name of any class # declaring one, and the native methods themselves. -keepclasseswithmembernames,includedescriptorclasses class * { native ; }