I decided to migrate the application to androidx using the migration tool. The migration process was successful. The only issue I am experiencing is to build the application on different configurations and also the application fails to deploy upon successful build process.
<AndroidDexTool>r8</AndroidDexTool> The application is able to build successfully without any error where i have no idea if this is the right way to assign the dex tool since it has only d8 and dx dex compiler<AndroidEnableMultiDex>True</AndroidEnableMultiDex> <AndroidDexGenerator>d8</AndroidDexGenerator><AndroidLinkTool>r8</AndroidLinkTool> I get a R8 error stating that missing class - okhttp3.callback which I have no nugget library reference for the class in my project.<AndroidEnableMultiDex>True</AndroidEnableMultiDex> <AndroidDexGenerator>d8</AndroidDexGenerator> I get a COMPILETODALVIK : Uncaught translation error : com.android.dx.cf.code.SimException: androidx.browser.trustedThe application should build and debug without any issues.
Based on the steps reproduce above here is the following behaviours:
Microsoft Visual Studio Enterprise 2019
Version 16.5.0
VisualStudio.16.Release/16.5.0+29911.84
Microsoft .NET Framework
Version 4.8.03752
Xamarin 16.5.000.521 (d16-5@b3ea41e)
Visual Studio extension to enable development for Xamarin.iOS and Xamarin.Android.
Xamarin Designer 16.5.0.470 (remotes/origin/d16-5@681de3fd6)
Visual Studio extension to enable Xamarin Designer tools in Visual Studio.
Xamarin Templates 16.5.49 (0904f41)
Templates for building iOS, Android, and Windows apps with Xamarin and Xamarin.Forms.
Xamarin.Android SDK 10.2.0.100 (d16-5/988c811)
Xamarin.Android Reference Assemblies and MSBuild support.
Mono: c0c5c78
Java.Interop: xamarin/java.interop/d16-5@fc18c54
ProGuard: xamarin/proguard/master@905836d
SQLite: xamarin/sqlite/3.28.0@46204c4
Xamarin.Android Tools: xamarin/xamarin-android-tools/d16-5@9f4ed4b
Xamarin.iOS and Xamarin.Mac SDK 13.14.1.39 (30e8706)
Xamarin.iOS and Xamarin.Mac Reference Assemblies and MSBuild support.
Sample log from the first step reproduced:
ADB0010: Deployment failed
Mono.AndroidTools.InstallFailedException: Failure [INSTALL_FAILED_INVALID_APK: Package couldn't be installed in /data/app/com.moot_technologies.moot_Technologies-1: Package /data/app/com.moot_technologies.moot_Technologies-1/base.apk code is missing]
at Mono.AndroidTools.Internal.AdbOutputParsing.CheckInstallSuccess(String output, String packageName) in E:\A_work\277\s\External\androidtools\Mono.AndroidTools\Internal\AdbOutputParsing.cs:line 341
at Mono.AndroidTools.AndroidDevice.<>c__DisplayClass95_0.1 t) in E:\A\_work\277\s\External\androidtools\Mono.AndroidTools\AndroidDevice.cs:line 753
at System.Threading.Tasks.ContinuationTaskFromResultTask1.InnerInvoke()
at System.Threading.Tasks.Task.Execute()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at AndroidDeviceExtensions.
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at AndroidDeviceExtensions.
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task)
at Xamarin.AndroidTools.AndroidDeploySession.
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task)
at Xamarin.AndroidTools.AndroidDeploySession.
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Xamarin.AndroidTools.AndroidDeploySession.
ADB0010: Mono.AndroidTools.InstallFailedException: Failure [INSTALL_FAILED_INVALID_APK: Package couldn't be installed in /data/app/com.moot_technologies.moot_Technologies-1: Package /data/app/com.moot_technologies.moot_Technologies-1/base.apk code is missing]
at Mono.AndroidTools.Internal.AdbOutputParsing.CheckInstallSuccess(String output, String packageName) in E:\A_work\277\s\External\androidtools\Mono.AndroidTools\Internal\AdbOutputParsing.cs:line 341
at Mono.AndroidTools.AndroidDevice.<>c__DisplayClass95_0.1 t) in E:\A\_work\277\s\External\androidtools\Mono.AndroidTools\AndroidDevice.cs:line 753
at System.Threading.Tasks.ContinuationTaskFromResultTask1.InnerInvoke()
at System.Threading.Tasks.Task.Execute()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at AndroidDeviceExtensions.
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at AndroidDeviceExtensions.
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task)
at Xamarin.AndroidTools.AndroidDeploySession.
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task)
at Xamarin.AndroidTools.AndroidDeploySession.
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Xamarin.AndroidTools.AndroidDeploySession.
Done building project "Moot Technologies.csproj" -- FAILED.
Any solution to correct the above error will be apprecaited.
Thanks for the report!
For (1), as you suspected, <AndroidDexTool>r8</AndroidDexTool> is not valid. Setting AndroidDexTool to any value except d8 or dx causes the build to skip the DEX compilation phase completely, so no DEX files are created for the application, resulting in the "code is missing" error. I have submitted a separate issue about improving the error message for that scenario: https://github.com/xamarin/xamarin-android/issues/4439.
For 2 and 3, note that the name AndroidDexGenerator is not used by Xamarin.Android. It won't cause problems to set that property, but also won't do anything. AndroidDexGenerator was mentioned on https://github.com/xamarin/xamarin-android/issues/2040, but the final property name that was implemented was AndroidDexTool, as documented on https://docs.microsoft.com/xamarin/android/deploy-test/building-apps/build-process.
Try setting your project back to the current recommended defaults. For example, remove all of the following properties from the .csproj file:
AndroidEnableMultiDexAndroidDexGeneratorAndroidLinkToolAndroidDexToolThis will let Xamarin.Android pick the current latest default values.
If the build fails after step 1 because of the DEX 64K reference limit, you can set AndroidEnableMultiDex back to True. The reason to try leaving it blank for step 1 is that Xamarin.Android 9.4 reduced the number of DEX references for common app scenarios, so multidex is often no longer needed.
If step 1 or 2 fails for a different reason (other than the DEX 64K reference limit), please collect the diagnostic MSBuild output for the failing build:
Zip up and attach back the file on this item. Note that the diagnostic Build output does contain environment variables, such as the Windows user name, so if you prefer to attach it privately a few options are:
/query @brendanzagaeski command from within the Xamarin.Android Gitter channel, and we can coordinate on another way to send the file non-publicly.If step 1 or 2 succeeds but you wish to enable R8 for app size reasons, you can now enable it at this step. If the build now fails, then again, please collect and attach back the diagnostic MSBuild output.
Thanks!
@brendanzagaeski thank you for your reply. Since my project has dex classes over 65K i removed the other properties as suggested in step 1 from the project file. I decided to go with step 2 but I still get the same error from R8 in the logs. This is the error that I am getting:
R8 : warning : Missing class: okhttp3.Callback
R8 : error : Compilation can't be completed because some library classes are missing.
I attached the ms build diagnostic file.
Output-Build Log with AndroidMultiDex enabled.txt
Yep something changed in VS 16.5 that wasn't there in 16.4, see #4416
@GuidoNeele Thanks for your reply. I ended up adding a proguard file and installing the missing nuget packages which was detected by the R8 link tool. After that i had to keep some classes references in the proguard to prevent R8 from removing them. I was not able to make the R8 to run without the proguard file when multi dex is enabled
Thanks for the log file and the additional info on your next steps. If I'm understanding correctly, it sounds like you've got your project building successfully now?
I was not able to make the R8 to run without the proguard file when multi dex is enabled
Depending on how the NuGet packages were set up, I suspect this might match https://github.com/xamarin/xamarin-android/issues/4449, so hopefully in the future there will be some improvements to let the build to pull in the ProGuard rules automatically from the NuGet package.
@gabrieldwight, apart from that issue of having to set up the ProGuard configuration file by hand, are there any other remaining questions for this issue?
Thanks!
Yep something changed in VS 16.5 that wasn't there in 16.4
One change in Xamarin.Android 10.2 compared to Xamarin.Android 10.1 that could account for getting new messages from R8 is that R8 is now used automatically instead of ProGuard if the AndroidEnableDesugar MSBuild property is true.
@brendanzagaeski Yes. I was able to get the project to build and run successfully. There is no question remaining for this issue.
Hi,
I've had a similar problem as @gabrieldwight. I figured out that in my android project file AndroidDexTool property is not set. After setting it to dx I was able to compile and run app. You can do this easily by going to Android project properties on Android Options tab and changing Dex compiler option to d8 and back to dx and saving changes. It'll add missing key.
I've the same problem with okhttp3. I installed the Square.OkHttp3 nuget and now I'm experiencing the following similar message but with another class:
R8 : warning : Missing class: org.conscrypt.ConscryptHostnameVerifier
I'm trying to configure proguard file as @gabrieldwight but I'm not able to make it working. Gabriel, it would be wonderful if you could share your working proguard file as an example, please.
Thanks in advance!
@oriolnoya I attach the proguard file that I used to solve compilation issues.
r8.txt The MSBuild will give any missing classes that is not included in the proguard when your application crash at startup. The missing classes that will be detected during build and runtime you add there class names or nuget packages if they have dependencies. Let me know if you are able to successfully build and run your project without any issues.
Thanks
@PeterSzp Thanks for your reply. That step will work without any problems. There are some androidx packages that can't build successfully with dx as dex link tool. Overall it will work with any packages that can work in any of dex environment assigned in the project.
@gabrieldwight, excellent. Glad to hear you've got your project working, and thanks for helping out with PeterSzp's and oriolnoya's questions!
@GuidoNeele Thanks for your reply. I ended up adding a proguard file and installing the missing nuget packages which was detected by the R8 link tool. After that i had to keep some classes references in the proguard to prevent R8 from removing them. I was not able to make the R8 to run without the proguard file when multi dex is enabled
Where did you put the proguard file and did you name it r8.txt? I would appreciate if you could give a detailed instructions step by step on how you solved your issue. I struggle with this for several days and more details would be very helpful. thx
@sereoja, in case it might help, note that the ProGuard configuration file can have any name as long as it is included in the project and the Build Action is set to ProguardConfiguration. See the documentation about customizing ProGuard, which also applies to R8:
https://docs.microsoft.com/xamarin/android/deploy-test/release-prep/proguard#customizing-proguard
If you get stuck after adding that file and checking for any missing library dependencies based on the error messages, feel free to submit a new issue with your diagnostic build output attached, and the team can take a look. Thanks in advance!
@oriolnoya I attach the proguard file that I used to solve compilation issues.
r8.txt The MSBuild will give any missing classes that is not included in the proguard when your application crash at startup. The missing classes that will be detected during build and runtime you add there class names or nuget packages if they have dependencies. Let me know if you are able to successfully build and run your project without any issues.Thanks
thanks for the file. 1 question why do you have for appcenter? have you ever encountered any problem? I was using proguard as Code Shrinker and never needed it? is it different for r8?
Beside that is it good use -keep class androidx.** { *; }.this will keep entire androidx libraries and you will not gain any shrinking. what i have for androidx libraries is as below
## AndroidX
-dontwarn com.google.android.**
-dontwarn com.google.android.material.**
-keep class com.google.android.material.** { *; }
-keep interface com.google.android.material.** { *; }
-keep public class com.google.android.material.R$* { *; }
-keep public class androidx.appcompat.widget.** { *; }
-keep public class androidx.preference.internal.** { *; }
-keep public class androidx.preference.internal.view.menu.** { *; }
-keep public class androidx.browser.customtabs.** { *; }
-keep class com.google.android.material.internal.BaselineLayout{ *; }
-dontwarn com.google.android.material.internal.BaselineLayout
-keep public class * extends androidx.core.view.ActionProvider {
public <init>(android.content.Context);
}
@brendanzagaeski does it make sense to use d8+r8 together with AndroidEnableMultiDex=true? by the way what is the setting called AndroidEnableMultipleDex? is it still an active setting?
@EmilAlipiev, in case you're still curious about about those questions, there's no harm in setting AndroidEnableMultiDex to true when using both D8 and R8, but if the minimum Android version is set to Android 5.0 Lollipop (API level 21) or higher, then AndroidEnableMultiDex won't change any build behavior because the R8 tool itself automatically enables multidex in that case.
by the way what is the setting called AndroidEnableMultipleDex? is it still an active setting?
That was an old incorrect property name that Visual Studio was setting in a couple versions back in 2017: https://xamarin.github.io/bugzilla-archives/56/56192/bug.html. That property can safely be removed from any projects where it is present.