How to stop extending UnityPlayerActivity — Unity Android

Martin Gonzalez
etermax technology
Published in
4 min readAug 17, 2018

I’ve been working with Unity for several years and there is a constant pattern on Unity Android Plugins that I think should be fixed — probably by the Unity team.

For those who don’t how Android plugins work, it’s something like this:

Let’s imagine…

We are planning to create an awesome plugin that will provide a cool feature and ,obviously, we want to share it with the Unity community Cool, right? Suppose we need to listen to some methods of the Activity lifecycle, hmm… I KNOW! WE EXTEND from UnityPlayerActivity, just like the documentation suggests.

Something doesn’t smell quite right here, but nevermind, let’s continue. So we build our plugin’s library, put it inside Assets/Plugins/Android, then edit the AndroidManifest.xml file (following the documentation example) like this:

Basically, what we are saying here is that the main activity of this application will be OverrideExample instead of UnityPlayerActivity.

We build our .apk file, test it on a few devices and we are done! We publish it and now everyone can use it!

Not so fast!

Suppose someone called, let’s call him Ed. Ed is a Unity developer from Europe who saw the plugin and said “COOL! This is exactly what I needed!” So he went and downloaded it, imported it, followed the instructions… but something happened along the way.

It turns out Ed has another plugin that is also extending from UnityPlayerActivity.And guess what? We can only have ONE of them. If Ed doesn’t know anything about Android or Java, he is in a big trouble… but if he knows a little bit about that, he can do one of two things:

Solutions

Quick and dirty approach:

According to this approach, Ed should create his OWN extension of UnityPlayerActivity and merge every other plugin that extended from it. That’s messy! Imagine having to recompile the .aar file for every plugin you want to integrate There must be some other non-dirty way!

Proposed Solution:

I don’t want to waste all your imagination, but let’s use it again just a little bit. I will share with you a small but powerful project that I developed, which solves this problem and, perhaps, could be implemented by Unity in a future update.

There are two important elements inside this project:

  • Android project: Containing what I would love for Unity to integrate.
  • Unity project: Containing an example of the proposed solution.

You will find that in this repo there are four java classes:

This structure would be the perfect solution, or at least in my opinion it would.

I will summarize what this really does:

UnityPlayerActivityExtension: It extends from UnityPlayerActivity(yes I know what you’re thinking… but this time it’s for a good cause!) One UnityPlayerActivityExtension to rule them all! It has every lifecycle method from the Activity (UnityPlayerActivity extends from Activity), and it also makes reference to UnityActivityLoader and UnityActivityListenerNotifier.

UnityActivityListenersLoader: Its job is to find every meta-data defined in the AndroidManifest.xml that starts with a com.unity.activity.listener prefix, so it can then instantiate the class corresponding to each of those keys and return a List of UnityActivityListener.

UnityActivityListener: It is the base class that your plugin must inherit in order to listen to Activity methods.

UnityActivityListenersNotifier: In every activity method, it will notify each of those UnityActivityListener instantiated by the Loader.

Let’s try it again!

We want to create an awesome Untiy Android Plugin but now imagine that this structure is provided by Unity. To make it clear, imagine that UnityPlayerActivityExtension is the real UnityPlayerActivity.

Now that Unity provides a way to listen to the Activity lifecycle methods, we don’t need to extend from UnityPlayerActivity anymore. We are now going to extend from a base class already provided, as many times as we need (Sweet! Right?).

This class is UnityActivityListener and it will allow us to override methods that the Activity has, like onCreate, onStart or onResume, etc…

Once we are done with our plugin– lets call it MyHelloWorldPlugin, which has a

MyHelloWorldActivityListener inside extending from UnityActivityListener — , the only thing left for us to do to make it work is to add these lines in the AndroidManifest.xml:

Pay attention to how I set the name com.unity.activity.listener.MyHelloWorld to the value com.unity.myhelloworldplugin.MyHelloWorldActivityListener, this will allow Unity to understand which class wants to listen to the main activity, so Unity will instantiate MyHelloWorldActivityListener and it will be working just like an activity (it’s not…, but don’t tell him is a lie… just let him think he is an activity).

Now we can build the .aar file, put it in Unity and build! Now Ed will have our plugin and any other plugin that tries to listen to UnityPlayerActivity.

Summary

Imagine a world in which every plugin provider follows this strategy. That would be really nice!

I hope Unity implements something like this on Android in the future!

Everybody can grab the project and use it, but it would be awesome to have it incorporated in Unity itself, so if you think this is a useful tool, here is the link to the Feature Request.

--

--

Martin Gonzalez
etermax technology

Software Developer working at Tactile Games Denmark, Unity developer for 10 years and I can not sit still. I love helping and learning from others.