android_plugin.rst 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376
  1. .. _doc_android_plugin:
  2. Godot Android plugins
  3. =====================
  4. Introduction
  5. ------------
  6. Android plugins are powerful tools to extend the capabilities of the Godot engine
  7. by tapping into the functionality provided by Android platforms and ecosystem.
  8. For example in Godot 4, Android plugins are used to support multiple Android-based
  9. XR platforms without encumbering the core codebase with vendor specific code or binaries.
  10. Android plugin
  11. --------------
  12. **Version 1 (v1)** of the Android plugin system was introduced in Godot 3 and compatible with Godot 4.0 and 4.1.
  13. That version allowed developers to augment the Godot engine with Java, Kotlin and native functionality.
  14. Starting in Godot 4.2, Android plugins built on the v1 architecture are now deprecated.
  15. Instead, Godot 4.2 introduces a new **Version 2 (v2)** architecture for Android plugins.
  16. v2 Architecture
  17. ^^^^^^^^^^^^^^^
  18. .. note::
  19. Godot Android plugin leverages the :ref:`Gradle build system <doc_android_gradle_build>`.
  20. Building on the previous v1 architecture, Android plugins continue to be derived from the
  21. `Android archive library <https://developer.android.com/studio/projects/android-library#aar-contents>`_.
  22. At its core, a Godot Android plugin v2 is an Android library with a dependency on the :ref:`Godot Android library <doc_android_library>`,
  23. and a custom Android library manifest.
  24. This architecture allows Android plugins to extend the functionality of the engine with:
  25. - Android platform APIs
  26. - Android libraries
  27. - Kotlin and Java libraries
  28. - Native libraries (via JNI)
  29. - GDExtension libraries
  30. Each plugin has an init class extending from the `GodotPlugin <https://github.com/godotengine/godot/blob/0a7f75ec7b465604b6496c8f5f1d638aed250d6d/platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPlugin.java#L80>`_ class
  31. which is provided by the :ref:`Godot Android library <doc_android_library>`.
  32. The ``GodotPlugin`` class provides APIs to access the running Godot instance and hook into its lifecycle. It is loaded at runtime by the Godot engine.
  33. v2 Packaging format
  34. ^^^^^^^^^^^^^^^^^^^
  35. v1 Android plugins required a custom ``gdap`` configuration file that was used by the Godot Editor to detect and load them.
  36. However this approach had several drawbacks, primary ones being that it lacked flexibility and departed from the `existing
  37. Godot EditorExportPlugin format, delivery and installation flow <https://docs.godotengine.org/en/stable/tutorials/plugins/editor/installing_plugins.html>`_.
  38. This has been resolved for v2 Android plugins by deprecating the ``gdap`` packaging and configuration mechanism in favor of
  39. the existing Godot ``EditorExportPlugin`` packaging format.
  40. The ``EditorExportPlugin`` API in turn has been extended to properly support Android plugins.
  41. Building a v2 Android plugin
  42. ----------------------------
  43. A github project template **is provided** at https://github.com/m4gr3d/Godot-Android-Plugin-Template as a **quickstart for building
  44. Godot Android plugins for Godot 4.2+**.
  45. You can follow the `template README <https://github.com/m4gr3d/Godot-Android-Plugin-Template#readme>`_
  46. to set up your own Godot Android plugin project.
  47. To provide further understanding, here is a break-down of the steps used to create the project template:
  48. 1. Create an Android library module using `these instructions <https://developer.android.com/studio/projects/android-library>`_
  49. 2. Add the Godot Android library as a dependency by updating the module's ``gradle`` `build file <https://github.com/m4gr3d/Godot-Android-Plugin-Template/blob/main/plugin/build.gradle.kts#L42>`_::
  50. dependencies {
  51. implementation("org.godotengine:godot:4.2.0.stable")
  52. }
  53. The Godot Android library is `hosted on MavenCentral <https://central.sonatype.com/artifact/org.godotengine/godot>`_, and updated for each release.
  54. 3. Create `GodotAndroidPlugin <https://github.com/m4gr3d/Godot-Android-Plugin-Template/blob/a01286b4cb459133bf07b11dfabdfd3980268797/plugin/src/main/java/org/godotengine/plugin/android/template/GodotAndroidPlugin.kt#L10>`_, an init class for the plugin extending `GodotPlugin <https://github.com/godotengine/godot/blob/0a7f75ec7b465604b6496c8f5f1d638aed250d6d/platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPlugin.java#L80>`_.
  55. - If the plugin exposes Kotlin or Java methods to be called from GDScript, they must be annotated with `@UsedByGodot <https://github.com/godotengine/godot/blob/0a7f75ec7b465604b6496c8f5f1d638aed250d6d/platform/android/java/lib/src/org/godotengine/godot/plugin/UsedByGodot.java#L45>`_. The name called from GDScript **must match the method name exactly**. There is **no** coercing ``snake_case`` to ``camelCase``. For example, from GDScript::
  56. if Engine.has_singleton("MyPlugin"):
  57. var singleton = Engine.get_singleton("MyPlugin")
  58. print(singleton.myPluginFunction("World"))
  59. - If the plugin uses `signals <https://docs.godotengine.org/en/stable/getting_started/step_by_step/signals.html>`_, the init class must return the set of signals used by overriding `GodotPlugin::getPluginSignals() <https://github.com/godotengine/godot/blob/fa3428ff25bc577d2a3433090478a6d615567056/platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPlugin.java#L302>`_. To emit signals, the plugin can use the `GodotPlugin::emitSignal(...) method <https://github.com/godotengine/godot/blob/0a7f75ec7b465604b6496c8f5f1d638aed250d6d/platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPlugin.java#L317>`_.
  60. 4. Update the plugin ``AndroidManifest.xml`` `file <https://github.com/m4gr3d/Godot-Android-Plugin-Template/blob/main/plugin/src/main/AndroidManifest.xml>`_ with the following meta-data::
  61. <meta-data
  62. android:name="org.godotengine.plugin.v2.[PluginName]"
  63. android:value="[plugin.init.ClassFullName]" />
  64. Where:
  65. - ``PluginName`` is the name of the plugin
  66. - ``plugin.init.ClassFullName`` is the full component name (package + class name) of the plugin init class (e.g: ``org.godotengine.plugin.android.template.GodotAndroidPlugin``).
  67. 5. Create the `EditorExportPlugin configuration <https://github.com/m4gr3d/Godot-Android-Plugin-Template/tree/main/plugin/export_scripts_template>`_ to package the plugin. The steps used to create the configuration can be seen in the `Packaging a v2 Android plugin`_ section.
  68. Building a v2 Android plugin with GDExtension capabilities
  69. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  70. Similar to GDNative support in v1 Android plugins, v2 Android plugins support the ability to integrate GDExtension capabilities.
  71. A github project template is provided at https://github.com/m4gr3d/GDExtension-Android-Plugin-Template as a quickstart for building
  72. GDExtension Android plugins for Godot 4.2+.
  73. You can follow the `template's README <https://github.com/m4gr3d/GDExtension-Android-Plugin-Template#readme>`_
  74. to set up your own Godot Android plugin project.
  75. Migrating a v1 Android plugin to v2
  76. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  77. Use the following steps if you have a v1 Android plugin you want to migrate to v2:
  78. 1. Update the plugin's manifest file:
  79. - Change the ``org.godotengine.plugin.v1`` prefix to ``org.godotengine.plugin.v2``
  80. 2. Update the Godot Android library build dependency:
  81. - You can continue using the ``godot-lib.<version>.<status>.aar`` binary from `Godot's download page <https://godotengine.org/download>`_ if that's your preference. Make sure it's updated to the latest stable version.
  82. - Or you can switch to the MavenCentral provided dependency::
  83. dependencies {
  84. implementation("org.godotengine:godot:4.2.0.stable")
  85. }
  86. 3. After updating the Godot Android library dependency, sync or build the plugin and resolve any compile errors:
  87. - The ``Godot`` instance provided by ``GodotPlugin::getGodot()`` no longer has access to a ``android.content.Context`` reference. Use ``GodotPlugin::getActivity()`` instead.
  88. 4. Delete the ``gdap`` configuration file(s) and follow the instructions in the `Packaging a v2 Android plugin`_ section to set up the plugin configuration.
  89. Packaging a v2 Android plugin
  90. -----------------------------
  91. As mentioned, a v2 Android plugin is now provided to the Godot Editor as an ``EditorExportPlugin`` plugin, so it shares a lot of the `same packaging steps <https://docs.godotengine.org/en/stable/tutorials/plugins/editor/making_plugins.html#creating-a-plugin>`_.
  92. 1. Add the plugin output binaries within the plugin directory (e.g: in ``addons/<plugin_name>/``)
  93. 2. Add the `tool script <https://docs.godotengine.org/en/stable/tutorials/plugins/editor/making_plugins.html#the-script-file>`_ for the export functionality within the plugin directory (e.g: in ``addons/<plugin_name>/``)
  94. - The created script must be a ``@tool`` script, or else it will not work properly
  95. - The export tool script is used to configure the Android plugin and hook it within the Godot Editor's export process. It should look something like this::
  96. @tool
  97. extends EditorPlugin
  98. # A class member to hold the editor export plugin during its lifecycle.
  99. var export_plugin : AndroidExportPlugin
  100. func _enter_tree():
  101. # Initialization of the plugin goes here.
  102. export_plugin = AndroidExportPlugin.new()
  103. add_export_plugin(export_plugin)
  104. func _exit_tree():
  105. # Clean-up of the plugin goes here.
  106. remove_export_plugin(export_plugin)
  107. export_plugin = null
  108. class AndroidExportPlugin extends EditorExportPlugin:
  109. # Plugin's name.
  110. var _plugin_name = "<plugin_name>"
  111. # Specifies which platform is supported by the plugin.
  112. func _supports_platform(platform):
  113. if platform is EditorExportPlatformAndroid:
  114. return true
  115. return false
  116. # Return the paths of the plugin's AAR binaries relative to the 'addons' directory.
  117. func _get_android_libraries(platform, debug):
  118. if debug:
  119. return PackedStringArray(["<paths_to_debug_android_plugin_aar_binaries>"])
  120. else:
  121. return PackedStringArray(["<paths_to_release_android_plugin_aar_binaries>"])
  122. # Return the plugin's name.
  123. func _get_name():
  124. return _plugin_name
  125. - Here are the set of `EditorExportPlugin APIs <https://docs.godotengine.org/en/stable/classes/class_editorexportplugin.html>`_ most relevant to use in this tool script:
  126. - `_supports_platform <https://docs.godotengine.org/en/latest/classes/class_editorexportplugin.html#class-editorexportplugin-method-supports-platform>`_: returns ``true`` if the plugin supports the given platform. For Android plugins, this must return ``true`` when ``platform`` is `EditorExportPlatformAndroid <https://docs.godotengine.org/en/stable/classes/class_editorexportplatformandroid.html>`_
  127. - `_get_android_libraries <https://docs.godotengine.org/en/latest/classes/class_editorexportplugin.html#class-editorexportplugin-method-get-android-libraries>`_: retrieve the local paths of the Android libraries binaries (AAR files) provided by the plugin
  128. - `_get_android_dependencies <https://docs.godotengine.org/en/latest/classes/class_editorexportplugin.html#class-editorexportplugin-method-get-android-dependencies>`_: retrieve the set of Android maven dependencies (e.g: `org.godot.example:my-plugin:0.0.0`) provided by the plugin
  129. - `_get_android_dependencies_maven_repos <https://docs.godotengine.org/en/latest/classes/class_editorexportplugin.html#class-editorexportplugin-method-get-android-dependencies-maven-repos>`_: retrieve the urls of the maven repos for the android dependencies provided by ``_get_android_dependencies``
  130. - `_get_android_manifest_activity_element_contents <https://docs.godotengine.org/en/latest/classes/class_editorexportplugin.html#class-editorexportplugin-method-get-android-manifest-activity-element-contents>`_: update the contents of the `<activity>` element in the generated Android manifest
  131. - `_get_android_manifest_application_element_contents <https://docs.godotengine.org/en/latest/classes/class_editorexportplugin.html#class-editorexportplugin-method-get-android-manifest-application-element-contents>`_: update the contents of the `<application>` element in the generated Android manifest
  132. - `_get_android_manifest_element_contents <https://docs.godotengine.org/en/latest/classes/class_editorexportplugin.html#class-editorexportplugin-method-get-android-manifest-element-contents>`_: update the contents of the `<manifest>` element in the generated Android manifest
  133. The ``_get_android_manifest_*`` methods allow the plugin to automatically provide changes
  134. to the app's manifest which are preserved when the Godot Editor is updated, resolving a long standing issue with v1 Android plugins.
  135. 3. Create a ``plugin.cfg``. This is an INI file with metadata about your plugin::
  136. [plugin]
  137. name="<plugin_name>"
  138. description="<plugin_description>"
  139. author="<plugin_author>"
  140. version="<plugin_version>"
  141. script="<relative_path_to_the_export_tool_script>"
  142. For reference, here is the `folder structure for the Godot Android plugin project template <https://github.com/m4gr3d/Godot-Android-Plugin-Template/tree/main/plugin/export_scripts_template>`_.
  143. At build time, the contents of the ``export_scripts_template`` directory as well as the generated plugin binaries are copied to the ``addons/<plugin_name>`` directory:
  144. .. code-block:: none
  145. export_scripts_template/
  146. |
  147. +--export_plugin.gd # export plugin tool script
  148. |
  149. +--plugin.cfg # plugin INI file
  150. Packaging a v2 Android plugin with GDExtension capabilities
  151. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  152. For GDExtension, we follow the same steps as for `Packaging a v2 Android plugin`_ and add the `GDExtension config file <https://docs.godotengine.org/en/stable/tutorials/scripting/gdextension/gdextension_cpp_example.html#using-the-gdextension-module>`_ in
  153. the same location as ``plugin.cfg``.
  154. For reference, here is the `folder structure for the GDExtension Android plugin project template <https://github.com/m4gr3d/GDExtension-Android-Plugin-Template/tree/main/plugin/export_scripts_template>`_.
  155. At build time, the contents of the ``export_scripts_template`` directory as well as the generated plugin binaries are copied to the ``addons/<plugin_name>`` directory:
  156. .. code-block:: none
  157. export_scripts_template/
  158. |
  159. +--export_plugin.gd # export plugin tool script
  160. |
  161. +--plugin.cfg # plugin INI file
  162. |
  163. +--plugin.gdextension # GDExtension config file
  164. Here is what the ``plugin.gdextension`` config file should look like::
  165. [configuration]
  166. entry_symbol = "plugin_library_init"
  167. compatibility_minimum = "4.2"
  168. android_aar_plugin = true
  169. [libraries]
  170. android.debug.arm64 = "res://addons/GDExtensionAndroidPluginTemplate/bin/debug/arm64-v8a/libGDExtensionAndroidPluginTemplate.so"
  171. android.release.arm64 = "res://addons/GDExtensionAndroidPluginTemplate/bin/release/arm64-v8a/libGDExtensionAndroidPluginTemplate.so"
  172. ...
  173. Of note is the ``android_aar_plugin`` field that specifies this GDExtension module is provided as part of a v2 Android plugin.
  174. During the export process, this will indicate to the Godot Editor that the GDExtension native shared libraries are exported by the Android plugin AAR binaries.
  175. For GDExtension Android plugins, the plugin init class must override `GodotPlugin::getPluginGDExtensionLibrariesPaths() <https://github.com/godotengine/godot/blob/0a7f75ec7b465604b6496c8f5f1d638aed250d6d/platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPlugin.java#L277>`_,
  176. and return the paths to the bundled GDExtension libraries config files (``*.gdextension``).
  177. The paths must be relative to the Android library's ``assets`` directory.
  178. At runtime, the plugin will provide these paths to the Godot engine which will use them to load and initialize the bundled GDExtension libraries.
  179. Using a v2 Android plugin
  180. -------------------------
  181. .. note::
  182. - Godot 4.2 or higher is required
  183. - v2 Android plugin requires the use of the `Gradle build process <https://docs.godotengine.org/en/stable/classes/class_editorexportplatformandroid.html#class-editorexportplatformandroid-property-gradle-build-use-gradle-build>`_.
  184. - The provided github project templates include demo Godot projects for quick testing.
  185. 1. Copy the plugin's output directory (``addons/<plugin_name>``) to the target Godot project's directory
  186. 2. Open the project in the Godot Editor; the Editor should detect the plugin
  187. 3. Navigate to ``Project`` -> ``Project Settings...`` -> ``Plugins``, and ensure the plugin is enabled
  188. 4. Install the Godot Android build template by clicking on ``Project`` -> ``Install Android Build Template...``
  189. 5. Navigate to ``Project`` -> ``Export...``
  190. 6. In the ``Export`` window, create an ``Android export preset``
  191. 7. In the ``Android export preset``, scroll to ``Gradle Build`` and set ``Use Gradle Build`` to ``true``
  192. 8. Update the project's scripts as needed to access the plugin's functionality. For example::
  193. if Engine.has_singleton("MyPlugin"):
  194. var singleton = Engine.get_singleton("MyPlugin")
  195. print(singleton.myPluginFunction("World"))
  196. 9. Connect an Android device to your machine and run the project on it
  197. Using a v2 Android plugin as an Android library
  198. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  199. Since they are also Android libraries, Godot v2 Android plugins can be stripped from their ``EditorExportPlugin`` packaging and provided as raw ``AAR`` binaries for use as libraries alongside the :ref:`Godot Android library <doc_android_library>` by Android apps.
  200. If targeting this use-case, make sure to include additional instructions for how the ``AAR`` binaries should be included (e.g: custom additions to the Android app's manifest).
  201. Reference implementations
  202. -------------------------
  203. - `Godot Android Plugins Samples <https://github.com/m4gr3d/Godot-Android-Samples/tree/master/plugins>`_
  204. - `Godot Android Plugin Template <https://github.com/m4gr3d/Godot-Android-Plugin-Template>`_
  205. - `GDExtension Android Plugin Template <https://github.com/m4gr3d/GDExtension-Android-Plugin-Template>`_
  206. - `Godot OpenXR Loaders <https://github.com/GodotVR/godot_openxr_loaders>`_
  207. Tips and Guidelines
  208. -------------------
  209. Simplify access to the exposed Java / Kotlin APIs
  210. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  211. To make it easier to access the exposed Java / Kotlin APIs in the Godot Editor, it's recommended to
  212. provide one (or multiple) gdscript wrapper class(es) for your plugin users to interface with.
  213. For example::
  214. class_name PluginInterface extends Object
  215. ## Interface used to access the functionality provided by this plugin.
  216. var _plugin_name = "GDExtensionAndroidPluginTemplate"
  217. var _plugin_singleton
  218. func _init():
  219. if Engine.has_singleton(_plugin_name):
  220. _plugin_singleton = Engine.get_singleton(_plugin_name)
  221. else:
  222. printerr("Initialization error: unable to access the java logic")
  223. ## Print a 'Hello World' message to the logcat.
  224. func helloWorld():
  225. if _plugin_singleton:
  226. _plugin_singleton.helloWorld()
  227. else:
  228. printerr("Initialization error")
  229. Support using the GDExtension functionality in the Godot Editor
  230. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  231. If planning to use the GDExtension functionality in the Godot Editor, it is recommended that the
  232. GDExtension's native binaries are compiled not just for Android, but also for the OS onto which
  233. developers / users intend to run the Godot Editor. Not doing so may prevent developers /
  234. users from writing code that accesses the plugin from within the Godot Editor.
  235. This may involve creating dummy plugins for the host OS just so the API is published to the
  236. editor. You can use the `godot-cpp-template <https://github.com/godotengine/godot-cpp-template>`__
  237. github template for reference on how to do so.
  238. Godot crashes upon load
  239. ^^^^^^^^^^^^^^^^^^^^^^^
  240. Check ``adb logcat`` for possible problems, then:
  241. - Check that the methods exposed by the plugin used the following Java types: ``void``, ``boolean``, ``int``, ``float``, ``java.lang.String``, ``org.godotengine.godot.Dictionary``, ``int[]``, ``byte[]``, ``float[]``, ``java.lang.String[]``.
  242. - More complex datatypes are not supported for now.