Browse Source

Add documentation for version 1 of the Godot Android plugin. (#2979)

Co-authored-by: Hugo Locurcio <[email protected]>
(cherry picked from commit ff2b3e4d001e3ceb3c3588b4b8b40737dbf20ccd)
Hugo Locurcio 5 years ago
parent
commit
26551cd3ed

+ 2 - 2
development/compiling/compiling_for_windows.rst

@@ -14,7 +14,7 @@ For compiling under Windows, the following is required:
   version 2017 or later. VS 2019 is recommended.
   version 2017 or later. VS 2019 is recommended.
   **Make sure to read "Installing Visual Studio caveats" below or you
   **Make sure to read "Installing Visual Studio caveats" below or you
   will have to run/download the installer again.**
   will have to run/download the installer again.**
-- `MinGW-w64 <http://mingw-w64.org/>`_ with GCC can be used as an alternative to
+- `MinGW-w64 <http://mingw-w64.org/>`__ with GCC can be used as an alternative to
   Visual Studio. Be sure to install/configure it to use the ``posix`` thread model.
   Visual Studio. Be sure to install/configure it to use the ``posix`` thread model.
 - `Python 3.5+ <https://www.python.org/downloads/windows/>`_.
 - `Python 3.5+ <https://www.python.org/downloads/windows/>`_.
 - `SCons 3.0 <https://www.scons.org>`_ build system. If using Visual Studio 2019,
 - `SCons 3.0 <https://www.scons.org>`_ build system. If using Visual Studio 2019,
@@ -160,7 +160,7 @@ Cross-compiling for Windows from other operating systems
 --------------------------------------------------------
 --------------------------------------------------------
 
 
 If you are a Linux or macOS user, you need to install
 If you are a Linux or macOS user, you need to install
-`MinGW-w64 <https://mingw-w64.org/doku.php>`_, which typically comes in 32-bit
+`MinGW-w64 <https://mingw-w64.org/doku.php>`__, which typically comes in 32-bit
 and 64-bit variants. The package names may differ based on your distribution,
 and 64-bit variants. The package names may differ based on your distribution,
 here are some known ones:
 here are some known ones:
 
 

+ 1 - 1
development/file_formats/tscn.rst

@@ -400,7 +400,7 @@ Each track is described by a list of key-value pairs in the format
 2. The ``path`` has the format ``NodePath(Path/To/Node:attribute)``.
 2. The ``path`` has the format ``NodePath(Path/To/Node:attribute)``.
    It's the path to the animated node or attribute, relative to the root node
    It's the path to the animated node or attribute, relative to the root node
    defined in the AnimationPlayer.
    defined in the AnimationPlayer.
-I 
+
 3. The ``interp`` is the method to interpolate frames from the keyframes.
 3. The ``interp`` is the method to interpolate frames from the keyframes.
    It is an enum variable with one of the following values:
    It is an enum variable with one of the following values:
 
 

+ 66 - 226
tutorials/plugins/android/android_plugin.rst

@@ -1,16 +1,16 @@
 .. _doc_android_plugin:
 .. _doc_android_plugin:
 
 
-Creating Android plugins
-========================
+Creating Android plugins (Godot 3.2.2+)
+=======================================
 
 
 Introduction
 Introduction
 ------------
 ------------
 
 
-Making video games portable is all fine and dandy, until mobile
-gaming monetization shows up.
+Android plugins are powerful tools to extend the capabilities of the Godot engine 
+by tapping into the functionality provided by the Android platform and ecosystem. 
 
 
-This area is complex, usually a mobile game that monetizes needs
-special connections to a server for things like:
+Mobile gaming monetization is one such example since it requires features 
+and capabilities that don't belong to the core feature set of a game engine:
 
 
 -  Analytics
 -  Analytics
 -  In-app purchases
 -  In-app purchases
@@ -29,246 +29,102 @@ special connections to a server for things like:
 -  Posting to Facebook, Twitter, etc.
 -  Posting to Facebook, Twitter, etc.
 -  Push notifications
 -  Push notifications
 
 
-On iOS, you can write a C++ module and take advantage of the C++/ObjC
-intercommunication. Even using GDNative is possible to make it a plug-in.
-
-On Android, interfacing with C++ through JNI (Java Native Interface) isn't as flexible, so writing plugins
-is considerably more work.
-
-It is also possible that you just want to do modifications to the Android export template, and by using a plugin your project
-can remain compatible with newer Godot versions (as the android source template will get updated on each release).
-
-Maybe REST
-----------
-
-Most of these APIs allow communication via REST/JSON APIs. If the API is relatively simple and does not require
-complex authentication, this may be a better idea than writing a specific Android plugin.
-
-Godot has great support for HTTP, HTTPS and JSON, so an API implemented this way
-will work on every platform, too. 
-
-Of course, in most of the cases, it's easier to just write an Android plugin, so keep reading.
+Making modifications to the Android export template is another use-case since using a plugin for that task allows the project
+to remain compatible with newer Godot versions.
 
 
 Android plugin
 Android plugin
 --------------
 --------------
 
 
-Writing an Android plugin is now possible, beginning with Godot 3.2. It's also pretty easy! Re-compiling the engine is no longer needed.
-
-Before anything, make sure you understand how to set up a :ref:`custom build environment<doc_android_custom_build>` for Android.
-
-Your plugin needs to be in a folder other than *"build/"* inside the *"res://android"* directory (which was created by following the link above). Any name is fine, so name it according to the SDK you will implement (or just your plugin name).
-
-Once created, there are certain rules to follow, but they are simple.
-
-Android directories
-^^^^^^^^^^^^^^^^^^^
-
-Inside your plugin folder, you can use the standard folders as if they were from an Android Gradle project. Examples of this are:
-
-.. code-block:: none
-
-   src/ - For Java source code, same as in your Android project
-   res/ - For resources
-   aidl/ - For interfaces
-   assets/ - For assets that will be included as-is on export
-   libs/debug - For debug JNI libraries
-   libs/release - For release JNI libraries
-
-Gradle will treat them as part of the project automatically when building, same as the default project files.
-
-"Chunk" files
-^^^^^^^^^^^^^
-
-It is now possible to modify *"AndroidManifest.xml"* and *build.gradle* in *"res://android/build"* directly and Godot will keep your
-changes when building. The problem, however, is that if you update Godot, you will also need to update the *build/* folder and your
-changes will be lost.
+While introduced in Godot 3.2.0, the Android plugin system got a significant architecture update starting with Godot 3.2.2. In Godot 4.0, the new architecture became
+the default, rendering plugins for Godot 3.2.0 incompatible with Godot 4.0.
 
 
-To overcome this, the Godot Android Plugin system lets you create *chunk* files, where you can specify little bits that can be
-inserted in both *"AndroidManifest.xml"* and *build.gradle*. They are inserted every time Godot builds the project for export or deploy.
+As a prerequisite, make sure you understand how to set up a :ref:`custom build environment<doc_android_custom_build>` for Android.
 
 
-AndroidManifest.conf
-~~~~~~~~~~~~~~~~~~~~
+At its core, a Godot Android plugin is a `Android archive library <https://developer.android.com/studio/projects/android-library#aar-contents>`_ (*aar* archive file) 
+with the following caveats:
 
 
-This file allows to insert bits of chunk into *AndroidManifest.xml*, the following are supported tags and are entirely optional:
+-  The library must have a dependency on the Godot engine library (``godot-lib.x.y.aar``). A stable version is made available for each Godot release.
 
 
-.. code-block:: none
+-  The library must include a specifically configured ``<meta-data>`` tag in its manifest file.
 
 
-   [user_permissions]
+Building a Android plugin
+^^^^^^^^^^^^^^^^^^^^^^^^^
 
 
-Any bit of text below this tag is inserted inside the <manifest> tag of the file. This is often used for permission tags.
+**Prerequisite:** `Android Studio <https://developer.android.com/studio>`_ is strongly recommended as the IDE to use to create Android plugins. 
+The instructions below assumes that you're using Android Studio.
 
 
-.. code-block:: none
+1.  Follow `these instructions <https://developer.android.com/studio/projects/android-library>`__ to create an Android library module for your plugin.
 
 
-   [application]
+2.  Add the Godot engine library as a dependency to your plugin module:
 
 
-Any bit of text below this tag inside the <application> tag of the file. Many SDKs require this.
+    -  Download the Godot engine library (godot-lib.x.y.aar)
 
 
-.. code-block:: none
+    -   Follow `these instructions <https://developer.android.com/studio/projects/android-library#AddDependency>`__ to add 
+        the Godot engine library as a dependency for your plugin.
 
 
-   [application_attribs]
+    -  In the plugin module's ``build.gradle`` file, replace ``implementation`` with ``compileOnly`` for the dependency line for the Godot engine library.
 
 
-These are attributes you can add at the end of the <application> tag. Some SDKs require this.
+3.  Create a new class in the plugin module and make sure it extends ``org.godotengine.godot.plugin.GodotPlugin``.
+    At runtime, it will be used to instantiate a singleton object that will be used by the Godot engine to load, initialize and run the plugin.
 
 
-gradle.conf
-~~~~~~~~~~~
+4.  Update the plugin ``AndroidManifest.xml`` file:
 
 
-This file allows to insert bits of chunk into *build.gradle*, the following are supported and are entirely optional:
+    -   Open the plugin ``AndroidManifest.xml`` file.
 
 
-.. code-block:: none
+    -   Add the ``<application></application>`` tag if it's missing.
 
 
-   [buildscript_repositories]
+    -   In the ``<application>`` tag, add a ``<meta-data>`` tag setup as follow::
+        
+            <meta-data 
+                android:name="org.godotengine.plugin.v1.[PluginName]" 
+                android:value="[plugin.init.ClassFullName]" />
 
 
+        Where ``PluginName`` is the name of the plugin, and ``plugin.init.ClassFullName`` is the full name (package + class name) of the plugin loading class.
 
 
-Any bit of text below this tag is inserted inside the buildscript.repositories section of the build file.
+5.  Add the remaining logic for your plugin and run the ``gradlew build`` command to generate the plugin's ``aar`` file. 
+    The build will likely generate both a ``debug`` and ``release`` ``aar`` files. Depending on your need, pick only one version (usually the ``release`` one) which to provide your users with.
 
 
+**Note:** The plugin's ``aar`` filename must match the following pattern: ``[PluginName]*.aar`` 
+where ``PluginName`` is the name of the plugin in camel case (e.g: ``GodotPayment.release.aar``).
 
 
-.. code-block:: none
+Loading and using a Android plugin
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 
-   [buildscript_dependencies]
+Once you have access to the plugin ``aar`` file, move it to the Godot project ``res://android/plugins`` directory.
 
 
+From your script:
 
 
-Any bit of text below this tag is inserted inside the buildscript.dependencies section of the build file.
+.. code::
 
 
-.. code-block:: none
+    if Engine.has_singleton("MyPlugin"):
+        var singleton = Engine.get_singleton("MyPlugin")
+        print(singleton.myPluginFunction("World"))
 
 
-   [allprojects_repositories]
+**When exporting the project**, you need to add the plugin's name to the ``Custom Template`` -> ``Plugins`` section.
+If trying to add multiple plugins, separate their names by a comma (``,``).
 
 
+Bundling GDNative resources
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+A Android plugin can define and provide C/C++ GDNative resources, either to provide and/or access functionality from the game logic.
+The GDNative resources can be bundled within the plugin ``aar`` file which simplifies the distribution and deployment process:
 
 
-Any bit of text below this tag is inserted inside the allprojects.repositories section of the build file.
-
-.. code-block:: none
-
-   [dependencies]
-
-
-Any bit of text below this tag is inserted inside the dependencies section of the build file.
-
-
-.. code-block:: none
-
-   [android_defaultconfig]
-
-
-Any bit of text below this tag is inserted inside the android.defaultconfig section of the build file.
-
-.. code-block:: none
-
-   [global]
-
-
-Any bit of text below this tag is inserted inside the global scope of the build file.
-
-Java singleton
---------------
+    -   The shared libraries (``.so``) for the defined GDNative libraries will be automatically bundled by the ``aar`` build system. 
 
 
-An Android plugin will usually have a singleton class that will load it,
-this class inherits from ``Godot.SingletonBase``. Resource identifiers for
-any additional resources you have provided for the module will be in the
-``com.godot.game.R`` class, so you'll likely want to import it.
+    -   Godot ``*.gdnlib`` and ``*.gdns`` resource files must be manually defined in the plugin ``assets`` directory. 
+        The recommended path for these resources relative to the ``assets`` directory should be: ``godot/plugin/v1/[PluginName]/``.
 
 
-A singleton object template follows:
+For GDNative libraries, the plugin singleton object must override the ``org.godotengine.godot.plugin.GodotPlugin::getPluginGDNativeLibrariesPaths()`` method, 
+and return the paths to the bundled GDNative libraries config files (``*.gdnlib``). The paths must be relative to the ``assets`` directory.
+At runtime, the plugin will provide these paths to Godot core which will use them to load and initialize the bundled GDNative libraries.
 
 
-.. code-block:: java
+Reference implementations
+^^^^^^^^^^^^^^^^^^^^^^^^^
+-   `Godot Oculus Mobile plugin <https://github.com/m4gr3d/godot_oculus_mobile/tree/2.0>`_
 
 
-    package org.godotengine.godot;
+    -   `Bundled gdnative resources <https://github.com/m4gr3d/godot_oculus_mobile/tree/2.0/plugin/src/main/assets/addons/godot_ovrmobile>`_
 
 
-    import android.app.Activity;
-    import android.content.Intent;
-    import android.content.Context;
-    import com.godot.game.R;
-    import javax.microedition.khronos.opengles.GL10;
+-   `Godot Payment plugin <https://github.com/m4gr3d/godot/tree/rearch_godot_android_plugin/platform/android/java/plugins/godotpayment>`_
 
 
-    public class MySingleton extends Godot.SingletonBase {
-
-        protected Activity appActivity;
-        protected Context appContext;
-        private Godot activity = null;
-        private int instanceId = 0;
-
-        public String myFunction(String p_str) {
-            // A function to bind.
-            return "Hello " + p_str;
-        }
-
-        public void getInstanceId(int pInstanceId) {
-            // You will need to call this method from Godot and pass in the get_instance_id().
-            instanceId = pInstanceId;
-        }
-
-        static public Godot.SingletonBase initialize(Activity p_activity) {
-            return new MySingleton(p_activity);
-        }
-
-        public MySingleton(Activity p_activity) {
-            // Register class name and functions to bind.
-            registerClass("MySingleton", new String[]
-                {
-                    "myFunction",
-                    "getInstanceId"
-                });
-            this.appActivity = p_activity;
-            this.appContext = appActivity.getApplicationContext();
-            // You might want to try initializing your singleton here, but android
-            // threads are weird and this runs in another thread, so to interact with Godot you usually have to do.
-            this.activity = (Godot)p_activity;
-            this.activity.runOnUiThread(new Runnable() {
-                    public void run() {
-                        // Useful way to get config info from "project.godot".
-                        String key = GodotLib.getGlobal("plugin/api_key");
-                        // SDK.initializeHere();
-                    }
-            });
-
-        }
-
-        // Forwarded callbacks you can reimplement, as SDKs often need them.
-
-        protected void onMainActivityResult(int requestCode, int resultCode, Intent data) {}
-        protected void onMainRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {}
-
-        protected void onMainPause() {}
-        protected void onMainResume() {}
-        protected void onMainDestroy() {}
-
-        protected void onGLDrawFrame(GL10 gl) {}
-        protected void onGLSurfaceChanged(GL10 gl, int width, int height) {} // Singletons will always miss first 'onGLSurfaceChanged' call.
-
-    }
-
-Calling back to Godot
-^^^^^^^^^^^^^^^^^^^^^
-
-Calling back to Godot from Java is a little more difficult. The instance
-ID of the script must be known first, this is obtained by calling
-``get_instance_ID()`` on the script. This returns an integer that can be
-passed to Java.
-
-From Java, use the ``calldeferred`` function to communicate back with Godot.
-Java will most likely run in a separate thread, so calls are deferred:
-
-.. code-block:: java
-
-    GodotLib.calldeferred(<instanceid>, "<function>", new Object[]{param1, param2, etc});
-
-
-Godot will detect this singleton and initialize it at the proper time.
-
-Using it from GDScript
-^^^^^^^^^^^^^^^^^^^^^^
-
-First you will need to add your singleton into the android modules to be loaded. Go to "Project > Project Settings".
-Then on the tab "General" go to the "Android" section, and fill the Modules part with your module name. 
-The module should include the full Java path. For our example: ``org/godotengine/godot/MySingleton``.
-
-.. image:: img/android_modules.png
-
-Then, from your script:
-
-::
-
-    if Engine.has_singleton("MySingleton"):
-        var singleton = Engine.get_singleton("MySingleton")
-        print(singleton.myFunction("World"))
 
 
 Troubleshooting
 Troubleshooting
 ---------------
 ---------------
@@ -278,21 +134,5 @@ Godot crashes upon load
 
 
 Check ``adb logcat`` for possible problems, then:
 Check ``adb logcat`` for possible problems, then:
 
 
--  Make sure libgodot_android.so is in the ``libs/armeabi`` folder
 -  Check that the methods used in the Java singleton only use simple
 -  Check that the methods used in the Java singleton only use simple
-   Java datatypes, more complex ones are not supported.
-
-Future
-------
-
-Godot has an experimental Java API Wrapper that allows to use the
-entire Java API from GDScript.
-
-It's simple to use and it's used like this:
-
-.. code-block:: none
-
-    class = JavaClassWrapper.wrap(<javaclass as text>)
-
-This is most likely not functional yet, if you want to test it and help
-us make it work, contact us on irc.freenode.org:#godotengine-devel.
+   Java datatypes. More complex datatypes are not supported.