Skip to content

Commit 55fa709

Browse files
jonathanpeppersjonpryor
authored andcommitted
[Xamarin.Android.Build.Tasks] default proguard rules for BroadcastReceiver (#4178)
Fixes: #4110 A crash was reported when using either Proguard or R8: java.lang.RuntimeException: Unable to get provider mono.MonoRuntimeProvider_1: java.lang.ClassNotFoundException: Didn't find class "mono.MonoRuntimeProvider_1" on path: DexPathList[[zip file "/data/app/myApp-61Sw26LCrQQYfOvCs2GsDw==/base.apk"],nativeLibraryDirectories=[/data/app/myapp-61Sw26LCrQQYfOvCs2GsDw==/lib/arm64, /data/app/myapp-61Sw26LCrQQYfOvCs2GsDw==/base.apk!/lib/arm64-v8a, /system/lib64, /system/product/lib64]] at android.app.ActivityThread.installProvider(ActivityThread.java:7152) at android.app.ActivityThread.installContentProviders(ActivityThread.java:6630) at android.app.ActivityThread.handleBindApplication(ActivityThread.java:6525) at android.app.ActivityThread.access$1400(ActivityThread.java:220) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1883) at android.os.Handler.dispatchMessage(Handler.java:107) at android.os.Looper.loop(Looper.java:224) at android.app.ActivityThread.main(ActivityThread.java:7520) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:539) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:950) Caused by: java.lang.ClassNotFoundException: Didn't find class "mono.MonoRuntimeProvider_1" on path: DexPathList[[zip file "/data/app/myapp-61Sw26LCrQQYfOvCs2GsDw==/base.apk"],nativeLibraryDirectories=[/data/app/myapp-61Sw26LCrQQYfOvCs2GsDw==/lib/arm64, /data/app/myapp-61Sw26LCrQQYfOvCs2GsDw==/base.apk!/lib/arm64-v8a, /system/lib64, /system/product/lib64]] at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:230) at java.lang.ClassLoader.loadClass(ClassLoader.java:379) at java.lang.ClassLoader.loadClass(ClassLoader.java:312) at android.app.AppComponentFactory.instantiateProvider(AppComponentFactory.java:147) at android.app.ActivityThread.installProvider(ActivityThread.java:7136) This could be reproduced in a new project, just by enabling a Code Shrinker and adding a `BroadcastReceiver`: [BroadcastReceiver(Process = ":remote", Name = "foo.MyReceiver")] public class MyReceiver : BroadcastReceiver { public override void OnReceive(Context context, Intent intent) { } } This generated a file in: obj\Release\100\android\src\mono\MonoRuntimeProvider_1.java We have no default proguard rule in `proguard_xamarin.cfg` that would cover inclusion of this Java class for ProGuard or R8. We can simply add a trailing `*` to the Java class name of an existing rule: -keep class mono.MonoRuntimeProvider* { *; <init>(...); } I also added a test for this scenario that will verify ProGuard & R8.
1 parent 1524e6e commit 55fa709

File tree

2 files changed

+16
-1
lines changed

2 files changed

+16
-1
lines changed

src/Xamarin.Android.Build.Tasks/Resources/proguard_xamarin.cfg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
-keep class android.support.multidex.MultiDexApplication { <init>(); }
66
-keep class com.xamarin.java_interop.** { *; <init>(); }
7-
-keep class mono.MonoRuntimeProvider { *; <init>(...); }
7+
-keep class mono.MonoRuntimeProvider* { *; <init>(...); }
88
-keep class mono.MonoPackageManager { *; <init>(...); }
99
-keep class mono.MonoPackageManager_Resources { *; <init>(...); }
1010
-keep class mono.android.** { *; <init>(...); }

src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest.cs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3607,6 +3607,19 @@ public void Desugar ([Values (true, false)] bool isRelease, [Values ("dx", "d8")
36073607
DexTool = dexTool,
36083608
LinkTool = linkTool,
36093609
};
3610+
3611+
//Add a BroadcastReceiver
3612+
proj.Sources.Add (new BuildItem.Source ("MyReceiver.cs") {
3613+
TextContent = () => @"
3614+
using Android.Content;
3615+
3616+
[BroadcastReceiver(Process = "":remote"", Name = ""foo.MyReceiver"")]
3617+
public class MyReceiver : BroadcastReceiver
3618+
{
3619+
public override void OnReceive(Context context, Intent intent) { }
3620+
}",
3621+
});
3622+
36103623
//Okhttp and Okio
36113624
//https://github.com/square/okhttp
36123625
//https://github.com/square/okio
@@ -3691,6 +3704,8 @@ public void foo()
36913704
var dexFile = builder.Output.GetIntermediaryPath (Path.Combine ("android", "bin", "classes.dex"));
36923705
FileAssert.Exists (dexFile);
36933706
Assert.IsTrue (DexUtils.ContainsClass (className, dexFile, AndroidSdkPath), $"`{dexFile}` should include `{className}`!");
3707+
className = "Lmono/MonoRuntimeProvider_1;";
3708+
Assert.IsTrue (DexUtils.ContainsClass (className, dexFile, AndroidSdkPath), $"`{dexFile}` should include `{className}`!");
36943709
}
36953710
}
36963711

0 commit comments

Comments
 (0)