2011-10-25 4 views
4

나는 (스칼라, 수입은 ommited)이 간단한 활동을 가지고 : 당신이 볼 수 있듯이안드로이드 (스칼라에서) : 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") 
    }) 
    } 
} 

mThreadrun이 꼬리 재귀 적으로 재정의, 즉시 시작, 그것은을 위해, mHandler에 잠을 빈 메시지를 전송 짧은 시간을 보내고 동일한 메시지를 다시 보냅니다. A의, 말,

private val mThread = new Thread { 
    override def run { 
     mHandler.sendEmptyMessage(0) 
     Thread.sleep(10) 
     run 
    } 
    } 

을 다른 곳으로 트리거 : 내가 생성 한 후 즉시 mThread를 시작하지 않는 경우 다음과 같이 이제

.... 
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) 
... 

: 활동이 시작되면,이 오류가 발생합니다 터치 이벤트 :

override def onTouchEvent(event: MotionEvent): Boolean = { 
    if (event.getAction == MotionEvent.ACTION_DOWN) 
     mThread.start 
    true 
    } 

일이 잘 될 것입니다.

설명 할 수 없습니다.

+0

수면 시간 초과를 100ms로 늘리면 어떻게됩니까? –

+0

결과는 같습니다. 스레드 문제를 언제 시작할 지 생각합니다. – Aufheben

+0

꼬리 재귀 최적화가 첫 번째 경우에는 작동하지 않는 것 같습니다. – starblue

답변

1

그래서 몇 가지 실험을했는데 꼬리 - 재귀 적으로 재정의 된 run이있는 스레드가 동일한 생성 식에서 시작되면 꼬리 - 호출 최적화가 실패 할 것이라고 결론을 내릴 수 있습니다. 오류가 발생할 수)

나쁜 :

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 
} 

PS를 Scala 2.9.1을 사용하고 있지만 라이브러리 크기가 작기 때문에 Android 개발 용으로 2.8.2를 사용하고 있습니다.

0

시작 스레드를 즉시 원하면 onCreate()에 넣지 않으시겠습니까? 잘 모르겠습니다 만, thread와 onCreate의 순서로 에러가 발생할 가능성이 있다고 생각합니다.

+0

실제로 무엇? ThreadOverflowError가 발생하지 않는다는 것을 알았습니다. 나는 이것이 dalvik 메카니즘이나 스칼라 클래스 초기화의 몇 가지 기본 세부 사항과 관련이 있다고 생각한다. – Aufheben

관련 문제