Kotlin出现java.lang.StackOverflowError: stack size 8MB

这两天用kotlin写程序的时候,突然出了这个异常,很好奇,然后搜了一下网上很多都是转载同一篇,并没有得到很有用的帮助,这里就当是做一个记录吧

一,StackOverflowError

java.lang.StackOverflowError:stacksize8MBStackOverflowError是由于当前线程的栈满了,也就是函数调用层级过多导致。堆栈溢出错误一般是递归调用。出现这种异常,大多是由于循环调用。出现的情况:大多数都是在本方法中调用本方法。也就是我们常说的递归调用,所以才导致这个错误的出现。

06-25 09:57:55.485 25963-25963/com.xp.wanandroid E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.xp.wanandroid, PID: 25963
    java.lang.StackOverflowError: stack size 8MB
        at com.xp.wanandroid.main.MainActivity$initView$$inlined$run$lambda$1.onNavigationItemSelected(MainActivity.kt)
        at android.support.design.widget.BottomNavigationView$1.onMenuItemSelected(BottomNavigationView.java:182)
        at android.support.v7.view.menu.MenuBuilder.dispatchMenuItemSelected(MenuBuilder.java:822)
        at android.support.v7.view.menu.MenuItemImpl.invoke(MenuItemImpl.java:171)
        at android.support.v7.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:973)
        at android.support.design.widget.BottomNavigationView.setSelectedItemId(BottomNavigationView.java:339)
        at com.xp.wanandroid.main.MainActivity$initView$$inlined$run$lambda$1.onNavigationItemSelected(MainActivity.kt:64)

06-25 09:57:55.536 25963-25963/com.xp.wanandroid D/Error: ERR: exClass=java.lang.StackOverflowError
    ERR: exMsg=stack size 8MB
    ERR: file=MainActivity.kt
    ERR: class=com.xp.wanandroid.main.MainActivity$initView$$inlined$run$lambda$1
    ERR: method=onNavigationItemSelected line=-1

这是我的异常,是在点击底部菜单的时候出现的。行数也很明显。

main_activity_main_bottomnav.run {
            setOnNavigationItemSelectedListener {
                selectedItemId = R.id.main_bottom_nav_item_home //64行:崩溃行
                bottomNavItemSelected(it.itemId)
            }
        }

这是崩溃地方的代码,最开始我并没有觉得这里有什么问题,其实是对kotlin用的不熟悉导致的。在selectListener中设置了id导致该listener会循环调用,然后导致了异常。

setOnNavigationItemSelectedListener有两种用法:

  • setOnNavigationItemSelectedListener(listener)直接在括号内传递一个listener这个跟java是一样的
  • setOnNavigationItemSelectedListener{ 具体回调 } 一种是将回调具体操作直接写在大括号{}内即可。

selectedItemId 是我想设置的默认菜单ID,却写进了listener里面,应该是写在run里面才对。对于Kotlin中run不熟悉的可以看这篇文章

改正后的代码:

main_activity_main_bottomnav.run {
            setOnNavigationItemSelectedListener {
                bottomNavItemSelected(it.itemId)
            }
            selectedItemId = R.id.main_bottom_nav_item_home
        }

这样就不会有异常了。

二,总结

其实出现StackOverflowError这样的异常,我们只需要遵循它的基本规则当前线程的栈满了找到异常的代码行,然后考虑使那个地方导致了循环调用,或者递归调用,然后改正他即可。俗话说万变不离其宗,报这种异常的地方有很多,但是不要慌,归根结底就是栈满了,找到导致栈满了的地方,改正即可。

贴一下项目吧。用kotlin写的android项目,欢迎互相交流学习。

kotlin之Android项目实战

你可能感兴趣的:(Kotlin相关)