There are a quite a few posts scattered around about this but my question is:
Has anyone managed to successfully build a MultiDex enabled app that utilizes a custom Application class that will run on pre - Lollipop devices?
For people who wanted to learn more about it keep reading.
The issues is that when creating a MultiDex app that uses a custom application class (I'd guess the vast majority of apps over the 65k limit would be in this category), that class does not end up in the first dex file which causes devices without built in MultiDex support to crash with the error
[AndroidRuntime] java.lang.RuntimeException: Unable to instantiate application md5a3fc106bb082f0a6c07b5025b0a464e3.MyApplication: java.lang.ClassNotFoundException: Didn't find class "md5a3fc106bb082f0a6c07b5025b0a464e3.MyApplication" on path
I've tried all of the listed solutions, including from Xamarin support in order to get to this to work.
There are numerous articles about it:
https://bugzilla.xamarin.com/show_bug.cgi?id=35491
https://bugzilla.xamarin.com/show_bug.cgi?id=38693
https://forums.xamarin.com/discussion/57485/multiple-issues-with-library-project-and-multidex
What I've done:
I have created a custom MultiDexMainDexList file by using a modified version of the mainDexClasses.bat file (as per the articles).
I then modified the command that Xamarin throws at it to use the full path names as Xamarin just tries to use "obj\Debug"
mainDexClasses_fixed.bat --output C:\Users\bradl_000\Documents\blocke79\App\App\obj\Debug\multidex.keep "'C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\MonoAndroid\v6.0\mono.android.jar';'C:\androidsdk\extras\android\support\multidex\library\libs\android-support-multidex.jar';'C:\Users\bradl_000\Documents\blocke79\App\App\obj\Debug__library_projects__\Aniways.AndroidBinding\library_project_imports\aniways-V2.3.08.jar'" (have trimmed this massive list for reading)
This produces a MultiDexMainDexList file with all of the classes in my project. which I then add this to my project with the new build action of "MultiDexMainDexList" (only available in Alpha channel v6).
This gets rid of the error regarding the application class but instead throws a new error regarding not being able to find the PackageManager class.
I then started thinking that I should trim down the entire list of classes in the MultiDexMainDexList file and keep only the ones that I think my custom application class needs to load. No matter what I've done to this list I still get the error regarding the PackageManager.
Has anyone traveled the same path with more success than me? Is it even possible?
Thanks to the genius of Alexandre Chohfi there is now a fix for this. Following the routine I described above to create the MultiDexMainDexList file using the custom batch file.
You then need to create the MultiDexApplication class below. In your custom application class overload this class instead of Application.
Details are here: https://bugzilla.xamarin.com/show_bug.cgi?id=40515
using System; using Android.App; using Android.Runtime; using Java.Interop; namespace Sample { [Register("android/support/multidex/MultiDexApplication", DoNotGenerateAcw = true)] public class MultiDexApplication : Application { internal static readonly JniPeerMembers _members = new XAPeerMembers("android/support/multidex/MultiDexApplication", typeof (MultiDexApplication)); internal static IntPtr java_class_handle; private static IntPtr id_ctor; [Register(".ctor", "()V", "", DoNotGenerateAcw = true)] public MultiDexApplication() : base(IntPtr.Zero, JniHandleOwnership.DoNotTransfer) { if (Handle != IntPtr.Zero) return; try { if (GetType() != typeof (MultiDexApplication)) { SetHandle( JNIEnv.StartCreateInstance(GetType(), "()V"), JniHandleOwnership.TransferLocalRef); JNIEnv.FinishCreateInstance(Handle, "()V"); return; } if (id_ctor == IntPtr.Zero) id_ctor = JNIEnv.GetMethodID(class_ref, "<init>", "()V"); SetHandle( JNIEnv.StartCreateInstance(class_ref, id_ctor), JniHandleOwnership.TransferLocalRef); JNIEnv.FinishCreateInstance(Handle, class_ref, id_ctor); } finally { } } protected MultiDexApplication(IntPtr javaReference, JniHandleOwnership transfer) : base(javaReference, transfer) { } internal static IntPtr class_ref { get { return JNIEnv.FindClass("android/support/multidex/MultiDexApplication", ref java_class_handle); } } protected override IntPtr ThresholdClass { get { return class_ref; } } protected override Type ThresholdType { get { return typeof (MultiDexApplication); } } } }
Answers
As an update the actual error about package manager is
java.lang.NoClassDefFoundError%3A+mono.MonoPackageManager_Resources
I've also posted on StackOverflow. Might get a better response there
http://stackoverflow.com/q/36502564/4349446
I have the same issue.
Switch Beta channel , Update to Xamarin 4.1.0.33 and Xamarin Studio 6.0.0 version!
They have fixed the bug!
My app can work below 5.0!Thanks Xamarin Team!
Hi klark - thanks for the heads up.
I've just upgraded and tried my app but I'm getting the same issue as before.
java.lang.NoClassDefFoundError: mono.MonoPackageManager_Resources.
Would you mind sharing you MultiDexKeepList file so I can compare with mine?
Having the same error as @BradleyLocke.1401 on the latest beta :
[AndroidRuntime] Shutting down VM [AndroidRuntime] FATAL EXCEPTION: main [AndroidRuntime] Process: com.eroad.driverna, PID: 31444 [AndroidRuntime] java.lang.NoClassDefFoundError: mono.MonoPackageManager_Resources [AndroidRuntime] at mono.MonoPackageManager.LoadApplication(MonoPackageManager.java:52) [AndroidRuntime] at mono.MonoRuntimeProvider.attachInfo(MonoRuntimeProvider.java:22) [AndroidRuntime] at android.app.ActivityThread.installProvider(ActivityThread.java:5199) [AndroidRuntime] at android.app.ActivityThread.installContentProviders(ActivityThread.java:4794) [AndroidRuntime] at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4734) [AndroidRuntime] at android.app.ActivityThread.access$1500(ActivityThread.java:166) [AndroidRuntime] at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1343) [AndroidRuntime] at android.os.Handler.dispatchMessage(Handler.java:102) [AndroidRuntime] at android.os.Looper.loop(Looper.java:136) [AndroidRuntime] at android.app.ActivityThread.main(ActivityThread.java:5590) [AndroidRuntime] at java.lang.reflect.Method.invokeNative(Native Method) [AndroidRuntime] at java.lang.reflect.Method.invoke(Method.java:515) [AndroidRuntime] at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1268) [AndroidRuntime] at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1084) [AndroidRuntime] at dalvik.system.NativeStart.main(Native Method)
Does anyone from Xamarin Support have anything to say about this one?
Thanks to the genius of Alexandre Chohfi there is now a fix for this. Following the routine I described above to create the MultiDexMainDexList file using the custom batch file.
You then need to create the MultiDexApplication class below. In your custom application class overload this class instead of Application.
Details are here: https://bugzilla.xamarin.com/show_bug.cgi?id=40515
A Xamarin guy helped this guy fix it.
https://www.jimbobbennett.io/fixing-issues-with-multidex-on-pre-lollipop-devices-on-windows/
@BradleyLocke
your solution working so thanks
But I override OnCreate() on MultiDexApplication class but this method does not call on application start
Have any idea about this issue.
i'm also getting this error and i have changed my mainDexClasses.bat file but still unable to run my project on pre-lollipop devices please help me with issue.
I'm having an issue where even after modifying the build process to ensure that the base application class (and dependencies) are in the first dex file, the app still fails on 4.4 devices. I can unpack the dex and confirm that the correct class files are there, but it still fails. Is this completely broken? I have resorted to rolling back to older versions of the support libraries to prevent my application from going over the 64k limit to bypass multidex altogether.
Also, does the linker only apply to .NET dlls or should it also apply to Java .class files? It currently has no affect on the size of the .class files.
Hello,
I'm working on a custom application class, I can make the application running which extends from MultiDexApplication but not custom application.
Any clues?
I got the similar issue on Mac. Does anyone solve the issue on Mac?
Which version of Xamarin Android SDK do you use? Look here:
https://forums.xamarin.com/discussion/comment/292493/#Comment_292493