如何在 GameActivity 中使用来自 SurfaceView 内部的 Toast 消息?
How to use Toast message from inside SurfaceView inside GameActivity?
以下是我项目中 GameActivity
和 GameView
的片段:
GameActivity.kt
class GameActivity : Activity() {
private var gameView: GameView? = null
// We override the oncreate to add the gameview which will be showing the game
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
var display = windowManager.defaultDisplay
val size = Point()
display.getSize(size)
gameView = GameView(this, size)
setContentView(gameView)
}
}
GameView.kt
class GameView(context: Context, private val size: Point) : SurfaceView(context), Runnable {
private val gameThread = Thread(this)
...
private fun prepareLevel() {}
...
private fun update (fps: Long) {
if (RectF.intersects(powerup.position, player.position)) {
Toast.makeText(context, "Powerup intersects", Toast.LENGTH_SHORT).show()
}
}
...
}
问题是当交集发生时代码中断并出现以下错误:
E/AndroidRuntime: FATAL EXCEPTION: Thread-2
Process: com.example.sacredanimals, PID: 3367
java.lang.RuntimeException: Can't toast on a thread that has not called Looper.prepare()
at android.widget.Toast$TN.<init>(Toast.java:390)
at android.widget.Toast.<init>(Toast.java:114)
at android.widget.Toast.makeText(Toast.java:277)
at android.widget.Toast.makeText(Toast.java:267)
at com.example.sacredanimals.GameView.update(GameView.kt:96)
at com.example.sacredanimals.GameView.run(GameView.kt:78)
at java.lang.Thread.run(Thread.java:764)
我进行了一些调试,问题的发生可能是因为应该在主线程而不是子线程之一上调用 Toast 消息,如 link 中所建议:
但是,对于我想从 SurfaceView
内部调用 Toast.message 的情况,我无法解决这个问题
Toast.makeText() 只能从 Main/UI 线程调用。 Looper.getMainLooper() 帮你实现:
Handler(Looper.getMainLooper()).post {
Toast.makeText(context, "Powerup intersects", Toast.LENGTH_SHORT).show()
}
以下是我项目中 GameActivity
和 GameView
的片段:
GameActivity.kt
class GameActivity : Activity() {
private var gameView: GameView? = null
// We override the oncreate to add the gameview which will be showing the game
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
var display = windowManager.defaultDisplay
val size = Point()
display.getSize(size)
gameView = GameView(this, size)
setContentView(gameView)
}
}
GameView.kt
class GameView(context: Context, private val size: Point) : SurfaceView(context), Runnable {
private val gameThread = Thread(this)
...
private fun prepareLevel() {}
...
private fun update (fps: Long) {
if (RectF.intersects(powerup.position, player.position)) {
Toast.makeText(context, "Powerup intersects", Toast.LENGTH_SHORT).show()
}
}
...
}
问题是当交集发生时代码中断并出现以下错误:
E/AndroidRuntime: FATAL EXCEPTION: Thread-2
Process: com.example.sacredanimals, PID: 3367
java.lang.RuntimeException: Can't toast on a thread that has not called Looper.prepare()
at android.widget.Toast$TN.<init>(Toast.java:390)
at android.widget.Toast.<init>(Toast.java:114)
at android.widget.Toast.makeText(Toast.java:277)
at android.widget.Toast.makeText(Toast.java:267)
at com.example.sacredanimals.GameView.update(GameView.kt:96)
at com.example.sacredanimals.GameView.run(GameView.kt:78)
at java.lang.Thread.run(Thread.java:764)
我进行了一些调试,问题的发生可能是因为应该在主线程而不是子线程之一上调用 Toast 消息,如 link 中所建议:
Toast.makeText() 只能从 Main/UI 线程调用。 Looper.getMainLooper() 帮你实现:
Handler(Looper.getMainLooper()).post {
Toast.makeText(context, "Powerup intersects", Toast.LENGTH_SHORT).show()
}