简体   繁体   中英

Kotlin - java.lang.IllegalStateException: Could not execute method for android:onClick

There is the XML layout

I past the code in pastebin because it's too long

I'm Trying To build the tic tac toe game and It's work Perfectly but when I click the last button that it's will be in the row the The app Get crush. it's work great but I don't know why it's give me this error

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.ziadabouelfarah.tictactoy, PID: 6182
    java.lang.IllegalStateException: Could not execute method for android:onClick
        at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:390)
        at android.view.View.performClick(View.java:6256)
        at android.view.View$PerformClick.run(View.java:24701)
        at android.os.Handler.handleCallback(Handler.java:789)
        at android.os.Handler.dispatchMessage(Handler.java:98)
        at android.os.Looper.loop(Looper.java:164)
        at android.app.ActivityThread.main(ActivityThread.java:6541)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
     Caused by: java.lang.reflect.InvocationTargetException
        at java.lang.reflect.Method.invoke(Native Method)
        at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:385)
        at android.view.View.performClick(View.java:6256) 
        at android.view.View$PerformClick.run(View.java:24701) 
        at android.os.Handler.handleCallback(Handler.java:789) 
        at android.os.Handler.dispatchMessage(Handler.java:98) 
        at android.os.Looper.loop(Looper.java:164) 
        at android.app.ActivityThread.main(ActivityThread.java:6541) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240) 
        at com.android.internal.os.ZygoteInit.amin(ZygoteInit.java:767) 
     Caused by: java.lang.IllegalArgumentException: bound must be positive
        at java.util.Random.nextInt(Random.java:388)
        at com.agefinder.hell.MainActivity.autoPlay(MainActivity.kt:173)
        at com.agefinder.hell.MainActivity.PlayGame(MainActivity.kt:54)
        at com.agefinder.hell.MainActivity.buSelect(MainActivity.kt:37)
        at java.lang.reflect.Method.invoke(Native Method) 
        at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:385) 
        at android.view.View.performClick(View.java:6256) 
        at android.view.View$PerformClick.run(View.java:24701) 
        at android.os.Handler.handleCallback(Handler.java:789) 
        at android.os.Handler.dispatchMessage(Handler.java:98) 
        at android.os.Looper.loop(Looper.java:164) 
        at android.app.ActivityThread.main(ActivityThread.java:6541) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767) 

And my code in Kotlin Is like the following:

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main)
    }


    fun buSelect(view:View){
        val buSelected= view as Button
        var cellID=0
        when(buSelected.id){
            R.id.bt1-> cellID=1
            R.id.bt2-> cellID=2
            R.id.bt3-> cellID=3
            R.id.bt4-> cellID=4
            R.id.bt5-> cellID=5
            R.id.bt6-> cellID=6
            R.id.bt7-> cellID=7
            R.id.bt8-> cellID=8
            R.id.bt9-> cellID=9

        }
        // Toast.makeText(this,"ID:"+ cellID, Toast.LENGTH_LONG).show()

        PlayGame(cellID,buSelected)
        Thread.sleep(500)
    }

    var player1=ArrayList<Int>()
    var player2=ArrayList<Int>()
    var ActivePlayer=1

    fun PlayGame(cellID:Int,buSelected:Button){

        if(ActivePlayer==1){
            buSelected.text="X"
            buSelected.setBackgroundResource(R.color.pink)
            player1.add(cellID)
            ActivePlayer=2
            //Thread.sleep(500)

            autoPlay()
        }else{
            buSelected.text="O"
            buSelected.setBackgroundResource(R.color.colorPrimaryDark)
            player2.add(cellID)
            ActivePlayer=1
        }


        buSelected.isEnabled=false
        CheckWiner()
    }



    fun  CheckWiner(){
        var winer=-1

        // row 1
        if(player1.contains(1) && player1.contains(2) && player1.contains(3)){
            winer=1
        }
        if(player2.contains(1) && player2.contains(2) && player2.contains(3)){
            winer=2
        }


        // row 2
        if(player1.contains(4) && player1.contains(5) && player1.contains(6)){
            winer=1
        }
        if(player2.contains(4) && player2.contains(5) && player2.contains(6)){
            winer=2
        }




        // row 3
        if(player1.contains(7) && player1.contains(8) && player1.contains(9)){
            winer=1
        }
        if(player2.contains(7) && player2.contains(8) && player2.contains(9)){
            winer=2
        }



        // col 1
        if(player1.contains(1) && player1.contains(4) && player1.contains(7)){
            winer=1
        }
        if(player2.contains(1) && player2.contains(4) && player2.contains(7)){
            winer=2
        }



        // col 2
        if(player1.contains(2) && player1.contains(5) && player1.contains(8)){
            winer=1
        }
        if(player2.contains(2) && player2.contains(5) && player2.contains(8)){
            winer=2
        }


        // col 3
        if(player1.contains(3) && player1.contains(6) && player1.contains(9)){
            winer=1
        }
        if(player2.contains(3) && player2.contains(6) && player2.contains(9)){
            winer=2
        }


        if(player1.contains(1) && player1.contains(5) && player1.contains(9)){
            winer=1
        }
        if(player2.contains(1) && player2.contains(5) && player2.contains(9)){
            winer=2
        }

        if(player1.contains(3) && player1.contains(5) && player1.contains(7)){
            winer=1
        }
        if(player2.contains(3) && player2.contains(5) && player2.contains(7)){
            winer=2
        }

        if( winer != -1){

            if (winer==1){
                Toast.makeText(this," Player 1  win the game", Toast.LENGTH_LONG).show()
            }else{
                Toast.makeText(this," Computer  win the game", Toast.LENGTH_LONG).show()

            }

        }

    }

    //var buSelect:Button?=null

    fun autoPlay(){

        var buSelect:Button?=null

        val emptyCells=ArrayList<Int>()
        for ( cellID in 1..9){

            if(!( player1.contains(cellID) || player2.contains(cellID))) {
                emptyCells.add(cellID)
            }
        }


        val r=Random()
        val randIndex=r.nextInt(emptyCells.size-0)+0
        val cellID= emptyCells[randIndex]


        buSelect = when(cellID){
            1-> bt1
            2-> bt2
            3-> bt3
            4-> bt4
            5-> bt5
            6-> bt6
            7-> bt7
            8-> bt8
            9-> bt9
            else->{
                bt1
            }
        }

        //Thread.sleep(500)

        PlayGame(
            cellID,
            buSelect!!
        )

    }


}

Could not execute method for android:onClick also means, that something was wrong with the execution, meaning there was an exception thrown from your onClick listener.

In your case r.nextInt(emptyCells.size-0)+0 is the culprit. The bound has to be positive, but emptyCells is empty and therefore emptyCells.size is 0.

You'd have to handle this case before. Eventually your game is finished anyway.

fun autoPlay(){
    var buSelect: Button? = null

    val emptyCells = ArrayList<Int>()
    for (cellID in 1..9) {
        if (!(player1.contains(cellID) || player2.contains(cellID))) {
            emptyCells.add(cellID)
        }
    }

    // if all cells have been checked, the game is over
    if (emptyCells.isEmpty()) return

    val r = Random()
    val randIndex = r.nextInt(emptyCells.size)
    val cellID = emptyCells[randIndex]

    buSelect = when(cellID) {
        1 -> bt1
        2 -> bt2
        3 -> bt3
        4 -> bt4
        5 -> bt5
        6 -> bt6
        7 -> bt7
        8 -> bt8
        9 -> bt9
        else -> {
            bt1
        }
    }

    //Thread.sleep(500)

    PlayGame(
        cellID,
        buSelect!!
    )
}

The issue is that you are calling with zero and it throws 并抛出

java.lang.IllegalArgumentException: bound must be positive

When your game ends ie when the last cell is clicked, all the cells will be consumed by both the player. So to avoid this error, simply add.

if(!emptyCells.isEmpty())
{
    val randIndex=r.nextInt(emptyCells.size-0)+0 
}
else 
{
    return
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM