Reputation: 1943
After migrating to AndroidX and updating all AndriodX packages to latest, builds would fail showing me three similar errors in build-generated XML files in obj
folder:
\obj\Debug\100\lp\117\jl\res\values\values.xml
: Found tag id where item is expectedThe XML file content is:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<id name="view_tree_lifecycle_owner"/>
</resources>
\obj\Debug\100\lp\121\jl\res\values\values.xml
: Found tag id where item is expectedThe XML file content is:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<id name="view_tree_saved_state_registry_owner"/>
</resources>
\obj\Debug\100\lp\123\jl\res\values\values.xml
: Found tag id where item is expectedThe XML file content is:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<id name="view_tree_view_model_store_owner"/>
</resources>
After looking for solutions online, I just changed <id name="...
to <item type="id" name="...
in each of the generated files and the build succeeded (even though I have to re-do this every time I clean/rebuild).
However, right after the app's splash screen, it app crashes showing the following exception:
Java.Lang.RuntimeException: 'Unable to get provider androidx.lifecycle.ProcessLifecycleOwnerInitializer: java.lang.ClassNotFoundException: Didn't find class "androidx.lifecycle.ProcessLifecycleOwnerInitializer" on path: DexPathList...
I looked that up and found many solutions suggesting enabling and/or configuring multi-dex, none of which ever worked.
The problem occurs only when linking is set to Sdk Assemblies Only
or Sdk and User Assemblies
.
Here's some of the configuration that didn't work with me:
I have tried enabling/disabling Enable Multi-Dex
in Android Options
tab in project properties.
I have tried setting android:name
attribute in application
tag in AndroidManifest.xml
to androidx.multidex.MultiDexApplication
.
I have tried to make MainApplication
class inherit from Android.Support.MultiDex.MultiDexApplication
(defined in XamarinLibrary.Xamarin.Android.Support.Multidex) instead of Android.App.Application
.
I have tried to make MainApplication
class inherit from manually created binding for AndroidX MultiDexApplication like this:
MultiDex.cs
:
using Android.Content;
using Android.Runtime;
using Java.Interop;
using System;
namespace OnePoint
{
[Register("androidx/multidex/MultiDex", DoNotGenerateAcw = true)]
public sealed class MultiDex : Java.Lang.Object
{
private static readonly JniPeerMembers _members = new XAPeerMembers("androidx/multidex/MultiDex", typeof(MultiDex));
internal static IntPtr class_ref => _members.JniPeerType.PeerReference.Handle;
public override JniPeerMembers JniPeerMembers => _members;
protected override IntPtr ThresholdClass => _members.JniPeerType.PeerReference.Handle;
protected override Type ThresholdType => _members.ManagedPeerType;
internal MultiDex(IntPtr javaReference, JniHandleOwnership transfer)
: base(javaReference, transfer)
{
}
[Register("install", "(Landroid/content/Context;)V", "")]
public static unsafe void Install(Context context)
{
try
{
JniArgumentValue* ptr = stackalloc JniArgumentValue[1];
*ptr = new JniArgumentValue(context?.Handle ?? IntPtr.Zero);
_members.StaticMethods.InvokeVoidMethod("install.(Landroid/content/Context;)V", ptr);
}
finally
{
}
}
[Register("installInstrumentation", "(Landroid/content/Context;Landroid/content/Context;)V", "")]
public static unsafe void InstallInstrumentation(Context instrumentationContext, Context targetContext)
{
try
{
JniArgumentValue* ptr = stackalloc JniArgumentValue[2];
*ptr = new JniArgumentValue(instrumentationContext?.Handle ?? IntPtr.Zero);
ptr[1] = new JniArgumentValue(targetContext?.Handle ?? IntPtr.Zero);
_members.StaticMethods.InvokeVoidMethod("installInstrumentation.(Landroid/content/Context;Landroid/content/Context;)V", ptr);
}
finally
{
}
}
}
}
MultiDexApplication.cs
:
using Android.App;
using Android.Runtime;
using Java.Interop;
using System;
namespace MyNamespace
{
[Register("androidx/multidex/MultiDexApplication", DoNotGenerateAcw = true)]
public class MultiDexApplication : Application
{
internal static readonly JniPeerMembers _members =
new XAPeerMembers("androidx/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 => JNIEnv.FindClass("androidx/multidex/MultiDexApplication", ref java_class_handle);
protected override IntPtr ThresholdClass => class_ref;
protected override Type ThresholdType => typeof(MultiDexApplication);
public override void OnCreate()
{
base.OnCreate();
MultiDex.Install(this);
}
}
}
update-package -reinstall
in Visual Studio's package manager console.Upvotes: 4
Views: 2517
Reputation: 41
I had to set the following
<AndroidUseAapt2>true</AndroidUseAapt2>
in the Android.csproj file to get this to work. (it was set to false and appears multiple times in the csproj file).
Upvotes: 2
Reputation: 1943
It turns out this problem was misleadingly reported by r8
dex compiler. When I changed the dex compiler to dx
, it reported a different compilation error: invalid opcode ba - invokedynamic requires --min-sdk-version >= 26 (currently 13)
even though the min-sdk-version
was not 13
. After looking up the latter error, thanks to this thread, I was able to resolve the problem by downgrading Xamarin.AndroidX.Browser
to version 1.0.0.1
(the latest version before 1.2.0
where the problem was introduced). After downgrading the mentioned package, I could successfully compile and run with either dx
or d8
.
Upvotes: 2
Reputation: 755
I had the same problem but only for the first XML that you mentioned (<id name="view_tree_lifecycle_owner"/>
)
I found an answer that worked for me (Release configuration with linking set to Sdk Assemblies Only
)
In the Android project properties, I enabled the "use incremental Android packaging system" checkbox under "Android Options." and that solved the issue.
I found the solution in this thread.
Upvotes: 6