我有這個簡單的活動(Scala中,進口中省略):Android(在Scala中):StackOverflowError取決於何時啓動線程?
class TestActivity extends Activity {
private val TAG = "TestActivity"
private val mHandler = new Handler {
override def handleMessage(msg: Message) {
Log.d(TAG, "handleMessage")
}
}
private val mThread = new Thread {
override def run {
mHandler.sendEmptyMessage(0)
Thread.sleep(10)
run
}
}.start
override def onCreate(savedInstanceState: Bundle) {
super.onCreate(savedInstanceState)
setContentView(new TextView(this) {
setText("hello, world")
})
}
}
正如你所看到的,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
}
事情會很好。
我無法解釋這一點。
如果將睡眠超時時間增加爲100ms會發生什麼? – 2011-10-25 03:52:39
結果是一樣的。我想什麼時候開始線程事宜。 – Aufheben
似乎尾遞歸優化在第一種情況下不起作用。 – starblue