與 Android API 整合
Android 平台擁有眾多 API 與豐富的第三方程式庫生態系,涵蓋推播通知、分析、身份驗證、廣告等各式功能。
這些功能不適合放進 Godot 核心,因此 Godot 早就提供了 Android 外掛系統。Android 外掛系統 讓開發者能以 Java 或 Kotlin 編寫 Godot 的 Android 外掛,並從 GDScript、C# 或 GDExtension 在 Godot 專案中存取與使用 Android API 與第三方程式庫。
class MyAndroidSingleton(godot: Godot?) : GodotPlugin(godot) {
@UsedByGodot
fun doSomething(value: String) {
// ...
}
}
然而撰寫 Android 外掛需要 Java 或 Kotlin 的知識,而多數 Godot 開發者並不具備。因此相當多的 Android API 與第三方程式庫沒有可供對接的 Godot 外掛。事實上,這也是許多開發者無法從其他遊戲引擎轉用 Godot 的主因之一。
為了解決這個問題,我們在 Godot 4.4 引入了幾個工具,簡化開發者存取 Android API 與第三方程式庫的流程。
JavaClassWrapper(Godot 單例)
JavaClassWrapper 是一個 Godot 單例,讓你僅用 GDScript、C# 或 GDExtension 就能建立 Java / Kotlin 類別的實例並呼叫其方法。
var LocalDateTime = JavaClassWrapper.wrap("java.time.LocalDateTime")
var DateTimeFormatter = JavaClassWrapper.wrap("java.time.format.DateTimeFormatter")
var datetime = LocalDateTime.now()
var formatter = DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm:ss")
print(datetime.format(formatter))
在上述程式碼片段中,透過 GDScript 使用 JavaClassWrapper 來存取 Java 的 LocalDateTime 與 DateTimeFormatter 類別。透過 JavaClassWrapper,我們可以像呼叫 GDScript 方法一樣,直接從 GDScript 呼叫這些 Java 類別的方法。
AndroidRuntime 外掛
JavaClassWrapper 很強大,但在 Android 上做許多事情需要存取各種生命週期/執行期物件。AndroidRuntime 外掛是 Godot 內建的 Android 外掛,可滿足這些需求。
結合 JavaClassWrapper 與 AndroidRuntime 外掛, 開發者無需離開 GDScript, 也不需要 Godot 以外的工具, 就能存取並使用 Android API。這對推廣以 Godot 進行 Android 開發而言影響 重大 :
如果你只需要做些簡單的事,或只用到第三方程式庫的一小部分,就不必製作外掛
它讓開發者能快速整合 Android 功能
它讓開發者僅用 GDScript 與
JavaClassWrapper就能打造 Godot 外掛(不需要 Java 或 Kotlin)
備註
對於使用 gradle 的匯出,Godot 會自動納入在專案 addons 目錄中找到的 .jar 或 .aar 檔案。因此要使用第三方程式庫,只需把其 .jar 或 .aar 檔放進 addons 目錄,並透過 JavaClassWrapper 直接在 GDScript 中呼叫其方法即可。
範例:顯示 Android toast
# Retrieve the AndroidRuntime singleton.
var android_runtime = Engine.get_singleton("AndroidRuntime")
if android_runtime:
# Retrieve the Android Activity instance.
var activity = android_runtime.getActivity()
# Create a Godot Callable to wrap the toast display logic.
var toast_callable = func():
# Use JavaClassWrapper to retrieve the android.widget.Toast class, then make and show a toast using the class APIs.
var ToastClass = JavaClassWrapper.wrap("android.widget.Toast")
ToastClass.makeText(activity, "This is a test", ToastClass.LENGTH_LONG).show()
# Wrap the Callable in a Java Runnable and run it on the Android UI thread to show the toast.
activity.runOnUiThread(android_runtime.createRunnableFromGodotCallable(toast_callable))
範例:讓裝置震動
# Retrieve the AndroidRuntime singleton.
var android_runtime = Engine.get_singleton("AndroidRuntime")
if android_runtime:
# Retrieve the Android Vibrator system service and check if the device supports it.
var vibrator_service = android_runtime.getApplicationContext().getSystemService("vibrator")
if vibrator_service and vibrator_service.hasVibrator():
# Configure and run a VibrationEffect.
var VibrationEffect = JavaClassWrapper.wrap("android.os.VibrationEffect")
var effect = VibrationEffect.createOneShot(500, VibrationEffect.DEFAULT_AMPLITUDE)
vibrator_service.vibrate(effect)
範例:存取內部類別
Java 的內部類別可使用 $ 符號來存取:
# Accessing 'VERSION' class, which is an inner class from the 'android.os.Build' class.
var version = JavaClassWrapper.wrap("android.os.Build$VERSION")
var sdk_int = version.SDK_INT
if sdk_int == 30:
# Do something specific on android 11 devices.
else:
# All other devices
範例:呼叫建構函式
建構函式是以與類別同名的方法來呼叫的。
此範例會建立一個用來傳送文字的 intent:
# Retrieve the AndroidRuntime singleton.
var android_runtime = Engine.get_singleton("AndroidRuntime")
if android_runtime:
var Intent = JavaClassWrapper.wrap("android.content.Intent")
var activity = android_runtime.getActivity()
var intent = Intent.Intent() # Call the constructor.
intent.setAction(Intent.ACTION_SEND)
intent.putExtra(Intent.EXTRA_TEXT, "This is a test message.")
intent.setType("text/plain")
activity.startActivity(intent)