Xamarin.Android MultiDex not working on <21 dev

2019-06-11 11:00发布

This seems to be a somewhat recent problem, and I am honestly not sure which problem is the real issue. Last week, after updating VS2017 and Android Support Libraries, I started getting the error "java.exe has exited with code 2". After searching, it seemed like the consensus was to enable MultiDex. So I did that, and it worked fine on newer phones. But when I tried to compile on a KitKat phone, I started to get missing class exceptions (but only when I logged with Android Monitor, no exceptions in VS).

I followed this link regarding custom application classes. I am using the correct bat file, and the right custom class. Everything still looks fine on 21+, but the old devices still reports that mono.MonoPackageManager is missing. When I go look at the multidex.keep generated in my debug folder, mono/MonoPackageManager.class is definitely in that file. So I really have no clue.

I generated an APK in order to inspect it with classyshark. I found a couple of interesting things there. My total number of methods is around 30K, so why is multidex even required if the limit is 65K? And also, I noticed that mono/MonoPackageManager is in classes2.dex, despite it being in my multidex.keep file.

Am I missing something obvious, or are there some major bugs in Xamarin.Android lately?

EDIT: Progress kind of made? Ignoring the fact that my project shouldn't even need multidex, I noticed that the multidex.keep file that was generated was only a single line with no spaces or anything. When I modified this file to put each class on a new line, then added that file with the build action MainDexMainDexList, everything works fine. I did not need to re-add the classes that it was previously complaining about. I have tried multiple versions of android build tools (specifically 25.0.2 and 26.0.1) with the same result. I think it is very strange that adding new lines fixes the issue, but the generated file does not have new lines.

2条回答
不美不萌又怎样
2楼-- · 2019-06-11 11:46

For me was combination of multiple solutions i found over the internets:

multidex.keep file in my project root

mono/android/app/ApplicationRegistration.class
mono/android/app/NotifyTimeZoneChanges.class
mono/MonoRuntimeProvider.class
mono/MonoPackageManager.class
mono/MonoPackageManager_Resources.class

manually add to .csproj to all build options

 <AndroidEnableMultipleDex>true</AndroidEnableMultipleDex>
 <AndroidEnableMultiDex>true</AndroidEnableMultiDex>

add to AndroidManifest.xml android-name attribute

<application android:name="android.support.multidex.MultiDexApplication">.....</application

in MainApplication class in Android folder add Register attribute

[Application]
[Register("android/support/multidex/MultiDexApplication", DoNotGenerateAcw = true)]
public class MainApplication : Application, Application.IActivityLifecycleCallbacks
{ ... }

Add Name to MainActivity

 [Activity(Name = "xx.xxx.MainActivity")]
 public class MainActivity : 
 global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
 { ... }

I am using appcenter.ms to build Andriod so change mainDexClasses.bat was NOT good solution. I tried THIS but this broke all other Android versions.

查看更多
淡お忘
3楼-- · 2019-06-11 12:02

I had the exact same issue and resolved it by creating a custom multidex.keep file in my project root folder and adding the following to it:

 mono/MonoPackageManager.class 
 mono/MonoRuntimeProvider.class
 mono/MonoPackageManager_Resources.class
 mono/android/app/NotifyTimeZoneChanges.class
 mono/android/app/ApplicationRegistration.class

This is in addition to any of my actual application classes it was complaining of not finding during runtime. This solved my <21 problems (especially for KitKat(19)).

The build system still creates a multidex.keep file, but that's in addition to my custom one, so it seems to work for me.

查看更多
登录 后发表回答