Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/356.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/233.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Android(在Scala中):StackOverflowerError取决于何时启动线程?_Java_Android_Multithreading_Scala_Stack Overflow - Fatal编程技术网

Java Android(在Scala中):StackOverflowerError取决于何时启动线程?

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

我有一个简单的活动(在Scala中,导入ommited):

如您所见,
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
}