Java Android(在Scala中):StackOverflowerError取决于何时启动线程?
我有一个简单的活动(在Scala中,导入ommited): 如您所见,Java Android(在Scala中):StackOverflowerError取决于何时启动线程?,java,android,multithreading,scala,stack-overflow,Java,Android,Multithreading,Scala,Stack Overflow,我有一个简单的活动(在Scala中,导入ommited): 如您所见,mThread立即启动,run被递归覆盖,它向mHandler发送一条空消息,短时间睡眠,然后再次发送相同的消息。当活动开始时,我收到以下错误: .... D/TestActivity(28224): handleMessage D/TestActivity(28224): handleMessage D/TestActivity(28224): handleMessage D/TestActivity(28224): han
mThread
立即启动,run
被递归覆盖,它向mHandler
发送一条空消息,短时间睡眠,然后再次发送相同的消息。当活动开始时,我收到以下错误:
....
D/TestActivity(28224): handleMessage
D/TestActivity(28224): handleMessage
D/TestActivity(28224): handleMessage
D/TestActivity(28224): handleMessage
I/dalvikvm(28224): threadid=9: stack overflow on call to Landroid/os/MessageQueue;.nativeWake:VI
I/dalvikvm(28224): method requires 8+20+0=28 bytes, fp is 0x43e33310 (16 left)
I/dalvikvm(28224): expanding stack end (0x43e33300 to 0x43e33000)
I/dalvikvm(28224): Shrank stack (to 0x43e33300, curFrame is 0x43e35fe0)
W/dalvikvm(28224): threadid=9: thread exiting with uncaught exception (group=0x40015560)
E/AndroidRuntime(28224): FATAL EXCEPTION: Thread-10
E/AndroidRuntime(28224): java.lang.StackOverflowError
E/AndroidRuntime(28224): at android.os.MessageQueue.enqueueMessage(MessageQueue.java:223)
E/AndroidRuntime(28224): at android.os.Handler.sendMessageAtTime(Handler.java:457)
E/AndroidRuntime(28224): at android.os.Handler.sendMessageDelayed(Handler.java:430)
E/AndroidRuntime(28224): at android.os.Handler.sendEmptyMessageDelayed(Handler.java:394)
E/AndroidRuntime(28224): at android.os.Handler.sendEmptyMessage(Handler.java:379)
E/AndroidRuntime(28224): at com.iped.audiotest.MainActivity$$anon$2.run(Activity.scala:20)
E/AndroidRuntime(28224): at com.iped.audiotest.MainActivity$$anon$2.run(Activity.scala:22)
E/AndroidRuntime(28224): at com.iped.audiotest.MainActivity$$anon$2.run(Activity.scala:22)
E/AndroidRuntime(28224): at com.iped.audiotest.MainActivity$$anon$2.run(Activity.scala:22)
...
现在,如果我没有在创建后立即启动mThread
,如下所示:
private val mThread = new Thread {
override def run {
mHandler.sendEmptyMessage(0)
Thread.sleep(10)
run
}
}
然后在其他地方触发,比如在触摸事件中:
override def onTouchEvent(event: MotionEvent): Boolean = {
if (event.getAction == MotionEvent.ACTION_DOWN)
mThread.start
true
}
一切都会好起来的
我无法解释这一点。如果您想立即启动线程,为什么不将其放在onCreate()中?
我不确定,但我认为thread和onCreate的顺序可能会导致错误。所以我做了一些实验,我必须得出结论,如果尾部被递归重写的线程在其创建的同一表达式中启动,尾部调用优化将失败(或者是导致错误的任何其他原因?) 坏的: 好:
另外,我正在运行Scala 2.9.1,但由于库的大小较小,所以在Android开发中使用了2.8.2。如果将睡眠超时增加到100ms会发生什么?结果是一样的。我认为什么时候开始线程很重要。在第一种情况下,似乎尾部递归优化不起作用。starblue,恐怕你是对的,请看我的回答,“声誉低于100的用户在提问后8小时内无法回答他们自己的问题。”,所以我稍后会发布,实际上我发现只要我不立即启动线程,StackOverflower错误就不会发生。我认为这与dalvik机制或scala类初始化的一些基本细节有关。
override def onTouchEvent(event: MotionEvent): Boolean = {
if (event.getAction == MotionEvent.ACTION_DOWN)
mThread.start
true
}
class Test {
val mThread = new Thread {
override def run {
println("hello")
run
}
}.start
}
class Test {
val mThread = new Thread {
override def run {
println("hello")
run
}
}
mThread.start
}