1
0
mirror of https://github.com/godotengine/godot.git synced 2025-11-04 12:00:25 +00:00

Android: Run clipboard tasks on UI thread

Fixes crashes on older Android versions (API level <= 27) by ensuring
that all clipboard operations are executed on the UI thread.
This commit is contained in:
Anish Mishra
2025-07-20 18:52:18 +05:30
parent 71a9948157
commit 67b45299c7

View File

@@ -38,7 +38,6 @@ import android.content.pm.PackageManager
import android.content.res.Configuration
import android.content.res.Resources
import android.graphics.Color
import android.graphics.Rect
import android.hardware.Sensor
import android.hardware.SensorManager
import android.os.*
@@ -79,6 +78,8 @@ import java.io.FileInputStream
import java.io.InputStream
import java.security.MessageDigest
import java.util.*
import java.util.concurrent.Callable
import java.util.concurrent.FutureTask
import java.util.concurrent.atomic.AtomicBoolean
import java.util.concurrent.atomic.AtomicReference
@@ -136,6 +137,16 @@ class Godot private constructor(val context: Context) {
val netUtils = GodotNetUtils(context)
private val godotInputHandler = GodotInputHandler(context, this)
private val hasClipboardCallable = Callable {
mClipboard?.hasPrimaryClip() == true
}
private val getClipboardCallable = Callable {
val clipData = mClipboard?.primaryClip
val text = clipData?.getItemAt(0)?.text
text?.toString() ?: ""
}
/**
* Task to run when the engine terminates.
*/
@@ -934,20 +945,32 @@ class Godot private constructor(val context: Context) {
@Keep
fun hasClipboard(): Boolean {
return mClipboard?.hasPrimaryClip() == true
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P || Looper.getMainLooper().thread == Thread.currentThread()) {
hasClipboardCallable.call()
} else {
val task = FutureTask(hasClipboardCallable)
runOnHostThread(task)
task.get()
}
}
@Keep
fun getClipboard(): String {
val clipData = mClipboard?.primaryClip ?: return ""
val text = clipData.getItemAt(0).text ?: return ""
return text.toString()
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P || Looper.getMainLooper().thread == Thread.currentThread()) {
getClipboardCallable.call()
} else {
val task = FutureTask(getClipboardCallable)
runOnHostThread(task)
task.get()
}
}
@Keep
fun setClipboard(text: String?) {
runOnHostThread {
mClipboard?.setPrimaryClip(ClipData.newPlainText("myLabel", text))
}
}
@Keep
private fun showFilePicker(currentDirectory: String, filename: String, fileMode: Int, filters: Array<String>) {