Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

No more extending UnityPlayerActivity! [Feature Request] [Storytelling]

Discussion in 'Android' started by Martin_Gonzalez, Apr 15, 2018.

?

Would be nice to have it in Unity?

Poll closed May 15, 2018.
  1. Yes

    100.0%
  2. No

    0 vote(s)
    0.0%
  3. I don' care

    0 vote(s)
    0.0%
  1. Martin_Gonzalez

    Martin_Gonzalez

    Joined:
    Mar 25, 2012
    Posts:
    361
    Hi everyone!

    I've been working with Unity several years and i saw a constant pattern on Unity Android Plugins that should be fixed, i think by Unity, or they should provide some kind of solution and every plugin provider must follow some practices.

    So i opened a feedback ticket to implement what you can find in this repository:

    https://github.com/MartinGonzalez/UnityPlayerActivityListener

    If you want a cleaner way to integrate android plugins you can vote this idea:

    https://feedback.unity3d.com/suggestions/provide-unityplayeractivity-events-for-unity-android

    For those who don't how several plugins work it's something like this...

    Let's imagine...

    We are going to create an awesome plugin that will resolve or provide some cool feature, and obviously we want to give it to the Unity community, cool right?
    So whatever we are going to we will need to listen some methods of the Activity lifecylce, jum... I KNOW! WE EXTEND THE UnityPlayerActivity, just like the documentation says here https://docs.unity3d.com/Manual/AndroidUnityPlayerActivity.html

    There is some smell here, but nevermind, let's continue... So we create our .aar file, put it inside Assets/Plugins/Android, we change a little the AndroidManifest.xml file like this (following the documentation example)

    Code (CSharp):
    1. <?xml version="1.0" encoding="utf-8"?>
    2.  
    3. <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.company.product">
    4.   <application android:icon="@drawable/app_icon" android:label="@string/app_name">
    5.     <activity android:name=".OverrideExample"
    6.              android:label="@string/app_name"
    7.              android:configChanges="fontScale|keyboard|keyboardHidden|locale|mnc|mcc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|uiMode|touchscreen">
    8.         <intent-filter>
    9.             <action android:name="android.intent.action.MAIN" />
    10.             <category android:name="android.intent.category.LAUNCHER" />
    11.         </intent-filter>
    12.     </activity>
    13.   </application>
    14. </manifest>

    Basically here we say that the main activity of this application will be OverrideExample instead of UnityPlayerActivity.

    We build our .apk file, test it on some devices and we finished! We published and everyone can use it!

    But...

    Somebody called, i don't know, Ed a Unity developer in Europe saw this plugin and said COOL! What i need! So he download it, imported it, follow the instructions but something happened.
    Ed has another plugin, that is also extending from UnityPlayerActivity, and 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 about that he could do two things!

    Solutions...

    Dirty way:


    Following this way, what Ed should do is to create his OWN extension of UnityPlayerActivity and merge every plugin that extend from UnityPLayerActivity...That's messy...
    Imagine recompiling the .aar file for every plugin you want to integrate... -_- Really? There must be some way! ... not dirty!

    Proposed Solution:

    I don't want to waste all your imagination, but let's use it again i little bit. I will share with you a small but powerfull project that i did and perhaps resolve this, also perhaps Unity can implement in a future update.

    Let's pick a look on this project: https://github.com/MartinGonzalez/UnityPlayerActivityListener

    Inside this project there are two important things

    • Android project, containing what i would love Unity integrate :D
    • Unity project, containing an example of this proposed solution.

    You will see that in: there are three java classes.
    This structure would be the perfect solution, or i think it's.
    I will summary what this really do:

    UnityPlayerActivityExtension extend from UnityPlayerActivity (...yes i know what you're thinking...) but this time is for a good cause! One UnityPlayerActivityExtension to rule them all...

    UnityPlayerActivityExtension has every lifecycle methods from the UnityPlayerActivity and also from the Activity itself (UnityPlayerActivity extend from Activity) and inside it has a UnityActivityListenerHelper.

    UnityActivityListenerHelper
    on it's creation will try to find every meta-data defined in the AndroidManifest.xml and every key of that meta-data that starts with com.unity.activity.listener.XXXXX prefix will be retrieve and will try to instanciate the value of that key, value would be the plugin class path that want to listen the main activity (in this case UnityPlayerActivityExtension)

    Let's do the same example as before, again, we want to create an awesome Untiy Android Plugin but now imagine that this structure of UnityPlayerActivityExtension is incorporated inside Unity, if you want to make it simpler, imagine that UnityPlayerActivityExtension is UnityPlayerActivity.

    Now that we know that unity provide us a way to listen the Activity events, we don't need to extend from UnityPlayerActivity anymore, now we are going to extend from an Abstract class that Unity will provide us (ou! nice! right?)
    This abstract class is AbstractUnityActivityListener and will allow us to override methods that the Activity has, like onCreate method, or onStart or onResume, etc...
    When we are done with our plugin, let's call it MyHelloWorldPlugin that inside has a
    MyHelloWorldActivityListener extending from AbstractUnityActivityListener the only thing that we will have to do to make this plugin work is to add in the AndroidManifest.xml something like this:

    Code (CSharp):
    1.     <application>
    2.         <meta-data
    3.             android:name="com.unity.activity.listener.MyHelloWorld"
    4.             android:value="com.unity.myhelloworldplugin.MyHelloWorldActivityListener" />
    5.     </application>
    See how i set as a key a concrete prefix com.unity.activity.listener and the .MyHelloWorld. This will allow "Unity" to understand that an ActivityListener class wants to listen, so "Unity" will instanciate MyHelloWorldActivityListener and it will be working just like an activity (but it's not...dont't tell him is a lie...he thinks he is an activity :p)

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

    Summary...

    Imagine every plugin provider following this strategy. Would be really nice!
    I hope Unity implement 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 :D

    Thanks for reaching the end! :D
     
    Last edited: Apr 15, 2018
  2. Virtumonde

    Virtumonde

    Joined:
    Apr 15, 2020
    Posts:
    84
  3. nonlin

    nonlin

    Joined:
    Dec 12, 2013
    Posts:
    46
    I don’t t understand Unity’s silence in regards to this. Even Unreal Engine has their own Unreal Programming Language so you can write to an xml file that will inject code into Unreal’s main activity but Unity has no answer to this nor cares to implement a solution?