java - Android IndexOutOfBoundException

标签 java android exception

我不知道我做错了什么,但我在我的应用程序中收到“IndexOutOfBoundException”。这是我的代码和 logcat:

//代码

public class GameView extends View {

  private Context myContext;
  private int scaledCardW;
  private int scaledCardH;
  private int screenH, screenW;
  private List<Card> deck = new ArrayList<Card>();
  private List<Card> myHand = new ArrayList<Card>();
  private List<Card> oppHand = new ArrayList<Card>();
  private List<Card> discardPile = new ArrayList<Card>();

  private float scale;
  private Paint blackPaint;
  private int oppScore;
  private int myScore;

  private boolean myTurn;

  private int movingCardIdx = -1;
  private int movingX;
  private int movingY;

  private int validRank = 8;
  private int validSuit = 0;

  private Bitmap cardBack;
  private Bitmap nextCardButton;

  private ComputerPlayer computerPlayer = new ComputerPlayer();

  private int scoreThisHand = 0;

  public GameView(Context context) {
    super(context);
    // TODO Auto-generated constructor stub
    myContext = context;

    scale = myContext.getResources().getDisplayMetrics().density;

    blackPaint = new Paint();
    blackPaint.setAntiAlias(true);
    blackPaint.setColor(Color.BLACK);
    blackPaint.setStyle(Paint.Style.STROKE);
    blackPaint.setTextAlign(Paint.Align.LEFT);
    blackPaint.setTextSize(scale * 15);

    //myTurn = new Random().nextBoolean();
    //myTurn = true;
  }

  @Override
    public void onSizeChanged(int w, int h, int oldw, int oldh)
    {
      super.onSizeChanged(w, h, oldw, oldh);
      screenH = h;
      screenW = w;

      initCards();

      dealCards();

      Bitmap tempBitmap = BitmapFactory.decodeResource(myContext.getResources(),R.drawable.card_back);

      nextCardButton = BitmapFactory.decodeResource(myContext.getResources(), R.drawable.arrow_next);

      scaledCardW = screenW/8;
      scaledCardH = (int) (scaledCardW*1.28);

      cardBack = Bitmap.createScaledBitmap(tempBitmap, scaledCardW,scaledCardH,false);

      validRank = discardPile.get(0).getRank();
      validSuit = discardPile.get(0).getSuit();

      myTurn = new Random().nextBoolean();
      if(!myTurn)
      {
        makeComputerPlay();
      }
    }

  private void initCards()
  {
    for(int x = 0; x < 4; x++)
    {

      for(int y = 102; y < 115; y++)
      {
        int tempId = y + (x * 100);

        Card tempCard = new Card(tempId);
        int resourceId = getResources().getIdentifier("card"+ tempId, "drawable",myContext.getPackageName());

        Bitmap tempBitmap = BitmapFactory.decodeResource(myContext.getResources(),resourceId);

        scaledCardW = screenW/8;
        scaledCardH = (int) (scaledCardW*1.28);
        Bitmap scaledBitmap = Bitmap.createScaledBitmap(tempBitmap,scaledCardW, scaledCardH, false);


        tempCard.setBmp(scaledBitmap);
        deck.add(tempCard);
      }

    }

  }

  private void drawCard(List<Card> handToDraw)
  {
    handToDraw.add(0,deck.get(0));
    deck.remove(0);

    if(deck.isEmpty())
    {
      for(int x = discardPile.size() -1; x > 0; x --)
      {
        deck.add(discardPile.get(0));
        discardPile.remove(0);
        Collections.shuffle(deck, new Random());
      }
    }
  }

  private void dealCards()
  {
    Collections.shuffle(deck, new Random());

    for(int y = 0; y < 7; y++)
    {
      drawCard(myHand);
      //drawCard(oppHand);
    }
  }

  @Override
    protected void onDraw(Canvas canvas) {

      //canvas.drawBitmap(deck.get(9).getBmp(), 80, 50,null);

      canvas.drawText("Computer Score: " + oppScore, 10, blackPaint.getTextSize() + 10, blackPaint);

      canvas.drawText("My Score: " + myScore, 10, (int)(screenH * 0.9) - blackPaint.getTextSize() - 10, blackPaint);



      for (int i = 0; i < oppHand.size(); i++)
      {
        canvas.drawBitmap(cardBack, i*(scale*5), blackPaint.getTextSize()+(50*scale), null);
      }

      canvas.drawBitmap(cardBack, (screenW/2)-cardBack.getWidth()-10, (screenH/2)-(cardBack.getHeight()/2), null);

      if (!discardPile.isEmpty())
      {
        canvas.drawBitmap(discardPile.get(0).getBmp(),(screenW/2)+10,(screenH/2)-(cardBack.getHeight()/2), null);
      }


      for (int i = 0; i < myHand.size(); i++) {
        if (i == movingCardIdx)
        {
          canvas.drawBitmap(myHand.get(i).getBmp(),
              movingX,
              movingY,
              null);
        }
        else
        {
          canvas.drawBitmap
            (myHand.get(i).getBmp(),
             i*(scaledCardW+5),
             screenH-blackPaint.
             getTextSize()-
             (50*scale), null);
        }
      }


      if (myHand.size() > 7)
      {
        canvas.drawBitmap(nextCardButton,
            screenW-nextCardButton.getWidth()-(30*scale),screenH-nextCardButton.getHeight()-scaledCardH-(90*scale),null);
      }

      for (int i = 0; i < myHand.size(); i++)
      {
        if (i == movingCardIdx)
        {
          canvas.drawBitmap(myHand.get(i).getBmp(),movingX, movingY, null);
        }
        else
        {
          if(i < 7)
          {
            canvas.drawBitmap(myHand.get(i).getBmp(),i*(scaledCardW+5),screenH-blackPaint.getTextSize()-(50*scale),null);
          }
        }

      }


      invalidate();

    }

  @Override
    public boolean onTouchEvent(MotionEvent event) {

      int eventaction = event.getAction();
      int X = (int)event.getX();
      int Y = (int)event.getY();
      switch (eventaction ) {
        case MotionEvent.ACTION_DOWN:

          if(myTurn)
          {
            for (int i = 0; i < 7; i++)
            {
              if (X > i*(scaledCardW+5) && X < i*(scaledCardW+5) + scaledCardW && Y > screenH-blackPaint.getTextSize()- (50*scale))
              {
                movingCardIdx = i;
                movingX = X-(int)(30*scale);
                movingY = Y-(int)(70*scale);
              }
            }

          }
          break;

        case MotionEvent.ACTION_MOVE:
          movingX = X-(int)(30*scale);
          movingY = Y-(int)(70*scale);
          break;

        case MotionEvent.ACTION_UP:

          if (movingCardIdx > -1 && X > (screenW/2)-(100*scale) && X < (screenW/2)+(100*scale) && Y > (screenH/2)-(100*scale) && Y < (screenH/2)+(100*scale) &&
              (myHand.get(movingCardIdx).getRank() == 8 || myHand.get(movingCardIdx).getRank() ==
               validRank || myHand.get(movingCardIdx).getSuit() == validSuit))
          {
            validRank = myHand.get(movingCardIdx).getRank();
            validSuit = myHand.get(movingCardIdx).getSuit();
            discardPile.add(0, myHand.get(movingCardIdx));
            myHand.remove(movingCardIdx);

            if(myHand.isEmpty())
            {
              endHand();
            }
            else
            {
              if(validRank == 8)
              {
                showChooseSuitDialog();
              }
              else
              {
                myTurn = false;
                makeComputerPlay();
              }
            }
          }
          movingCardIdx = -1;

          if (movingCardIdx == -1 && myTurn && X > (screenW/2)-(100*scale) && X < (screenW/2)+(100*scale) &&
              Y > (screenH/2)-(100*scale) && Y < (screenH/2)+(100*scale))
          {
            if (checkForValidDraw())
            {
              drawCard(myHand);
            }
            else
            {
              Toast.makeText(myContext, "You have a valid play.", Toast.LENGTH_SHORT).show();
            }

          }

          if (myHand.size() > 7 && X > screenW-nextCardButton.getWidth()-(30*scale) && Y > screenH-nextCardButton.getHeight()-scaledCardH- (90*scale) &&
              Y < screenH-nextCardButton.getHeight()-scaledCardH - (60*scale))
          {
            Collections.rotate(myHand, 1);
          }

          break;
      }

      invalidate();
      return true;
    }

  private void showChooseSuitDialog()
  {
    final Dialog chooseSuitDialog = new Dialog(myContext);
    chooseSuitDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
    chooseSuitDialog.setContentView(R.layout.choose_suit_dialog);
    final Spinner suitSpinner = (Spinner)chooseSuitDialog.findViewById(R.id.suitSpinner);
    ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(myContext, R.array.suits,android.R.layout.simple_spinner_item);
    adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    suitSpinner.setAdapter(adapter);
    Button okButton = (Button) chooseSuitDialog.findViewById(R.id.okButton);
    okButton.setOnClickListener(new View.OnClickListener()
        {
        @Override
        public void onClick(View view)
        {
        validSuit = (suitSpinner.
          getSelectedItemPosition()+1)*100;
        String suitText = "";
        if (validSuit == 100) {
        suitText = "Diamonds";
        } else if (validSuit == 200) {
        suitText = "Clubs";
        } else if (validSuit == 300) {
        suitText = "Hearts";
        } else if (validSuit == 400) {
        suitText = "Spades";
        }
        chooseSuitDialog.dismiss();
        Toast.makeText(myContext,"You chose " + suitText,Toast.LENGTH_SHORT).show();

        myTurn = false;
        makeComputerPlay();
        }
        });

    chooseSuitDialog.show();
  }

  private boolean checkForValidDraw()
  {
    boolean canDraw = true;
    for (int i = 0; i < myHand.size(); i++)
    {
      int tempId = myHand.get(i).getId();
      int tempRank = myHand.get(i).getRank();
      int tempSuit = myHand.get(i).getSuit();
      if (validSuit == tempSuit || validRank == tempRank || tempId == 108 || tempId == 208 ||tempId == 308 || tempId == 408)
      {
        canDraw = false;
      }
    }
    return canDraw;
  }


  private void makeComputerPlay()
  {
    int tempPlay = 0;
    while (tempPlay == 0)
    {
      tempPlay = computerPlayer.makePlay(oppHand,validSuit, validRank);
      if (tempPlay == 0)
      {
        drawCard(oppHand);
      }
    }
    if (tempPlay == 108 || tempPlay == 208 || tempPlay == 308 || tempPlay == 408)
    {
      validRank = 8;
      validSuit = computerPlayer.chooseSuit(oppHand);
      String suitText = "";
      if (validSuit == 100)
      {
        suitText = "Diamonds";
      }
      else if (validSuit == 200)
      {
        suitText = "Clubs";
      }
      else if (validSuit == 300)
      {
        suitText = "Hearts";
      }
      else if (validSuit == 400)
      {
        suitText = " Spades";
      }
      Toast.makeText(myContext, "Computer chose " + suitText, Toast.LENGTH_SHORT).show();
    }
    else
    {
      validSuit = Math.round((tempPlay/100) * 100);
      validRank = tempPlay - validSuit;
    }

    for (int i = 0; i < oppHand.size(); i++)
    {

      Card tempCard = oppHand.get(i);
      if (tempPlay == tempCard.getId())
      {
        discardPile.add(0, oppHand.get(i));
        oppHand.remove(i);
      }
    }

    if(oppHand.isEmpty())
    {
      endHand();
    }

    myTurn = true;

  }



  private void updateScores()
  {
    for (int i = 0; i < myHand.size(); i++)
    {
      oppScore += myHand.get(i).getScoreValue();
      scoreThisHand += myHand.get(i).getScoreValue();
    }

    for (int i = 0; i < oppHand.size(); i++)
    {
      myScore += oppHand.get(i).getScoreValue();
      scoreThisHand += oppHand.get(i).getScoreValue();
    }

  }

  private void endHand()
  {
    final Dialog endHandDialog = new Dialog(myContext);
    endHandDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
    endHandDialog.setContentView(R.layout.end_hand_dialog);
    updateScores();
    TextView endHandText = (TextView)endHandDialog.findViewById(R.id.endHandText);
    if (myHand.isEmpty())
    {
      if(myScore >= 300)
      {
        endHandText.setText("You reached " + myScore + " points. You won! Would you like to play again?");

      }
      else
      {
        endHandText.setText("You went out and got " + scoreThisHand + " points!");
      }
    }
    else if (oppHand.isEmpty())
    {
      if (oppScore >= 300)
      {
        endHandText.setText("The computer reached " + oppScore + " points. Sorry, you lost. Would you like to play again?");
      }
      else
      {
        endHandText.setText("The computer went out and got " + scoreThisHand + " points.");
      }
    }


    Button nextHandButton = (Button)endHandDialog.findViewById(R.id.nextHandButton);
    if (oppScore >= 300 || myScore >= 300)
    {
      nextHandButton.setText("New Game");
    }

    nextHandButton.setOnClickListener(new View.OnClickListener()
        {
        @Override
        public void onClick(View view)
        {
        if (oppScore >= 300 || myScore >= 300)
        {
        myScore = 0;
        oppScore = 0;
        }

        initNewHand();
        endHandDialog.dismiss();
        }

        });

    endHandDialog.show();

  }

  private void initNewHand() {
    // TODO Auto-generated method stub

    scoreThisHand = 0;
    if (myHand.isEmpty())
    {
      myTurn = true;
    }
    else if (oppHand.isEmpty())
    {
      myTurn = false;
    }
    deck.addAll(discardPile);
    deck.addAll(myHand);
    deck.addAll(oppHand);

    discardPile.clear();
    myHand.clear();
    oppHand.clear();

    dealCards();
    drawCard(discardPile);

    validSuit = discardPile.get(0).getSuit();
    validRank = discardPile.get(0).getRank();

    if (!myTurn)
    {
      makeComputerPlay();
    }
  }


}

//这是我的 LogCat

 error opening trace file: No such file or directory (2)
 GC_FOR_ALLOC freed 34K, 7% free 2395K/2572K, paused 88ms, total 91ms
 Grow heap (frag case) to 3.210MB for 770432-byte allocation
 GC_FOR_ALLOC freed <1K, 6% free 3147K/3328K, paused 100ms, total 100ms
 GC_CONCURRENT freed <1K, 6% free 3265K/3448K, paused 23ms+25ms, total 186ms
 Emulator without GPU emulation detected.
 GC_CONCURRENT freed 245K, 11% free 3524K/3920K, paused 75ms+53ms, total 455ms
 WAIT_FOR_CONCURRENT_GC blocked 194ms
 GC_CONCURRENT freed 315K, 12% free 3673K/4160K, paused 14ms+29ms, total 370ms
 WAIT_FOR_CONCURRENT_GC blocked 212ms
 GC_CONCURRENT freed 287K, 11% free 3853K/4320K, paused 78ms+64ms, total 441ms
 WAIT_FOR_CONCURRENT_GC blocked 182ms
 GC_CONCURRENT freed 352K, 12% free 3961K/4500K, paused 9ms+28ms, total 363ms
 WAIT_FOR_CONCURRENT_GC blocked 243ms
 GC_CONCURRENT freed 314K, 11% free 4105K/4600K, paused 98ms+61ms, total 434ms
 WAIT_FOR_CONCURRENT_GC blocked 234ms
 GC_CONCURRENT freed 352K, 12% free 4268K/4820K, paused 9ms+80ms, total 530ms
 WAIT_FOR_CONCURRENT_GC blocked 215ms
 GC_FOR_ALLOC freed 193K, 12% free 4244K/4820K, paused 68ms, total 70ms
 Grow heap (frag case) to 4.583MB for 316480-byte allocation
 GC_FOR_ALLOC freed <1K, 12% free 4553K/5132K, paused 147ms, total 147ms
 Shutting down VM
 threadid=1: thread exiting with uncaught exception (group=0x40a71930)
 FATAL EXCEPTION: main
 java.lang.IndexOutOfBoundsException: Invalid index 0, size is 0
      at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:251)
      at java.util.ArrayList.get(ArrayList.java:304)
      at com.example.crazyeights.GameView.onSizeChanged(GameView.java:94)
      at android.view.View.setFrame(View.java:14094)
      at android.view.View.layout(View.java:14006)
      at android.widget.FrameLayout.onLayout(FrameLayout.java:448)
      at android.view.View.layout(View.java:14008)
      at android.view.ViewGroup.layout(ViewGroup.java:4373)
      at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1663)
      at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1521)
      at android.widget.LinearLayout.onLayout(LinearLayout.java:1434)
      at android.view.View.layout(View.java:14008)
      at android.view.ViewGroup.layout(ViewGroup.java:4373)
      at android.widget.FrameLayout.onLayout(FrameLayout.java:448)
      at android.view.View.layout(View.java:14008)
      at android.view.ViewGroup.layout(ViewGroup.java:4373)
      at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:1892)
      at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1711)
      at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:989)
      at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:4351)
      at android.view.Choreographer$CallbackRecord.run(Choreographer.java:749)
      at android.view.Choreographer.doCallbacks(Choreographer.java:562)
      at android.view.Choreographer.doFrame(Choreographer.java:532)
      at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:735)
      at android.os.Handler.handleCallback(Handler.java:725)
      at android.os.Handler.dispatchMessage(Handler.java:92)
      at android.os.Looper.loop(Looper.java:137)
      at android.app.ActivityThread.main(ActivityThread.java:5041)
      at java.lang.reflect.Method.invokeNative(Native Method)
      at java.lang.reflect.Method.invoke(Method.java:511)
      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
      at dalvik.system.NativeStart.main(Native Method)
 Sending signal. PID: 929 SIG: 9
 GC_FOR_ALLOC freed 38K, 8% free 2395K/2576K, paused 326ms, total 332ms
 Grow heap (frag case) to 3.210MB for 770432-byte allocation
 GC_FOR_ALLOC freed <1K, 6% free 3147K/3332K, paused 79ms, total 79ms
 GC_CONCURRENT freed <1K, 6% free 3273K/3452K, paused 31ms+29ms, total 163ms
 Emulator without GPU emulation detected.

最佳答案

在您的 onSizeChanged() 中,您访问 discardPile 的第一个元素与 get(0)但是discardPile为空。

关于java - Android IndexOutOfBoundException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21599870/

相关文章:

android - 通过android电子邮件客户端发送大量信息

android - XML 选择器背景不适用于 2.3

java - 从字符串数组中获取特定项目

C++:std::map 抛出 out_of_range 异常

Oracle:如何以编程方式安排终止当前连接?

java - 使用表单元素上传图像时出现错误

Java SWT - 组内的 ScrolledComposite

java - 如何在 Java 中为图像添加边框?

java - 在android中获取versionCode时包管理器死掉了

java - 即使类路径中存在依赖项,Spring Boot也会显示 'can not be resolved'