0

There is a 3rd party library I need to use, that includes a class decorated with the [Application] attribute. This causes compiler errors since I have my own application class that uses an [Application] attribute. I would like my application class to inherit from the 3rd party lib's application class.

public class MyApplication : ThirdPartyApplication
{
}

however since I can't decorate my class with the [Application] attribute I have no way to specify in the Manifest that it should run "MyApplication" and not "ThirdPartyApplication".

If I manually add an entry into AndroidManifest.xml

<application
    android:name="com.your.packagename.MyApplication"
    android:icon="@drawable/luncher_icon"
    android:label="@string/app_name">

It will get replaced after the project gets built with

<application
    android:name="mdxxx.ThirdPartyApplication"
    android:icon="@drawable/luncher_icon"
    android:label="@string/app_name">

Does anyone know how to handle this situation in Xamarin Android?

Keep in mind that the 3rd party library can not be modified.

An alternate solution would be a way to disable all manifest generating attributes and manually create the AndroidManifest. There does not seem to be any way to do this either.

The below post is the exact situation I am having but in pure Android. Note that due to the above issues that this solution will not work for Xamarin.

how-to-handle-multiple-application-classes-in-android

Scott
  • 306
  • 3
  • 8

1 Answers1

0

So I was able to figure out a solution but it boarders on being a hack.

In short the android manifest is going to be modified using MSBuild.

Step 1: Have your custom application class inherit from the the Third Party lib's custom application and decorate your class with the "Register" tag.

[Register("com.namespace.MyApplication")]
public class MyApplication : ThirdPartyApplication
{
}

Step 2: Have your project include the RoslynCodeTaskFactory NuGet package

Step 3: Unload your project, then add the following in the Project tag

<UsingTask TaskName="UpdateManifest" TaskFactory="CodeTaskFactory" AssemblyFile="$(RoslynCodeTaskFactory)" Condition=" '$(RoslynCodeTaskFactory)' != '' ">
<ParameterGroup>
  <AndroidManifestFilename ParameterType="System.String" Required="true" />
  <ApplicationName ParameterType="System.String" Required="true" />
</ParameterGroup>
<Task>
  <Reference Include="System.Core" />
  <Using Namespace="System" />
  <Using Namespace="System.Xml" />
  <Code Type="Fragment" Language="cs"><![CDATA[
        XmlDocument doc = new XmlDocument();
        doc.Load(AndroidManifestFilename);
        XmlNode node = doc.DocumentElement.SelectSingleNode("/manifest/application");
        node.Attributes["android:name"].InnerText = ApplicationName;
        doc.Save(AndroidManifestFilename);
      ]]></Code>
</Task>
</UsingTask>
<Target Name="CleanManifest" AfterTargets="_GenerateJavaStubs">
   <UpdateManifest AndroidManifestFilename="$(ProjectDir)\obj\$(Configuration)\android\AndroidManifest.xml" ApplicationName="com.namespace.MyApplication" />
</Target>

Step 4: Reload the project and build. The manifest should now point to custom application class. If you get a class not found runtime exception most likely you forgot to add [Register] from Step 1.

Scott
  • 306
  • 3
  • 8