Can Kotlin be used for Android plugins? If yes, then what has to be done in order to make it work? I tried adding a Kotlin class to my plugin then calling it from the main Java singleton, but Gradle wouldn't find it. I think the documentation for Android plugins is lacking a lot of details.
Kotlin for Android plugins
I found a way to make it work:
gradle.conf
for the plugin:
[buildscript_dependencies]
classpath 'com.android.tools.build:gradle:3.2.1'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
[dependencies]
api ('org.jetbrains.kotlin:kotlin-stdlib:1.3.71')
api ('org.jetbrains.kotlin:kotlin-stdlib-common:1.3.71')
This adds the kotlin standard library as a dependency, and applies the kotlin-android
plugin. You also need to apply it in build.gradle
of the build
module (res://android/build/build.gradle
):
1. Add apply plugin: 'kotlin-android'
under buildscript{}
.
2. Also, add ext.kotlin_version = '1.3.71'
to buildscript{}
to specify the kotlin version to use.
This is how the top part of it will look like:
buildscript {
apply from: 'config.gradle'
ext.kotlin_version = '1.3.71' // This part is added
repositories {
google()
jcenter()
//CHUNK_BUILDSCRIPT_REPOSITORIES_BEGIN
//CHUNK_BUILDSCRIPT_REPOSITORIES_END
}
dependencies {
classpath libraries.androidGradlePlugin
//CHUNK_BUILDSCRIPT_DEPENDENCIES_BEGIN
//CHUNK_BUILDSCRIPT_DEPENDENCIES_END
}
}
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android' // This part is added
Now for the plugin itself:
The tree
for an example plugin:
example
├── gradle.conf
└── src
├── Example.kt
└── ExampleSingleton.java
ExampleSingleton.java
:
package org.godotengine.godot;
import android.app.Activity;
import android.content.Intent;
import android.content.Context;
import com.godot.game.R;
import javax.microedition.khronos.opengles.GL10;
import org.godotengine.godot.Example;
public class ExampleSingleton extends Godot.SingletonBase {
static public Godot.SingletonBase initialize(Activity p_activity) {
return new Example(p_activity);
}
}
This is just used as an interface for Godot to make it able to initialize our Kotlin class.
Example.kt
is a translation of the example Java singleton class provided in the documentation, but without the initiailize
function, since that is defined in ExampleSingleton.java
:
package org.godotengine.godot
import android.app.Activity
import android.content.Intent
import android.content.Context
import com.godot.game.R
import javax.microedition.khronos.opengles.GL10
class Example(p_activity: Activity): Godot.SingletonBase() {
protected var appActivity: Activity
protected var appContext: Context
private var activity: Godot? = null
private var instanceId = 0
fun myFunction(p_str: String): String {
// A function to bind.
return "Hello $p_str"
}
fun getInstanceId(pInstanceId: Int) {
// You will need to call this method from Godot and pass in the get_instance_id().
instanceId = pInstanceId
}
// Forwarded callbacks you can reimplement, as SDKs often need them.
override fun onMainActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {}
override fun onMainRequestPermissionsResult(requestCode: Int, permissions: Array<String?>?, grantResults: IntArray?) {}
override fun onMainPause() {}
override fun onMainResume() {}
override fun onMainDestroy() {}
override fun onGLDrawFrame(gl: GL10?) {}
override fun onGLSurfaceChanged(gl: GL10?, width: Int, height: Int) {} // Singletons will always miss first 'onGLSurfaceChanged' call.
init {
// Register class name and functions to bind.
registerClass("ExampleSingleton", arrayOf(
"myFunction",
"getInstanceId"
))
appActivity = p_activity
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.
activity = p_activity as Godot
activity?.apply {
runOnUiThread(object : Runnable {
override fun run() {
// Useful way to get config info from "project.godot".
val key: String = GodotLib.getGlobal("plugin/api_key")
// SDK.initializeHere();
}
})
}
}
}
Now in Godot: Import the Java singleton class as a module (org/godotengine/godot/ExampleSingleton
):
Now you should be ready to use the plugin in GDScript as shown in the documentation:
if Engine.has_singleton("ExampleSingleton"):
var singleton = Engine.get_singleton("ExampleSingleton")
print(singleton.myFunction("World"))
Result from logcat
:
04-10 16:10:22.064 25301 25325 I godot : Hello World