2016-11-29 164 views
-1

我想編寫Android Studio中生活一個簡單的GUI遊戲,但每當我嘗試運行它,應用程序意外關閉。 Android監視器不斷拋出InflateException。我在這個網站上查了很多關於InflateException的帖子,但是他們都沒有幫助我的情況。Android Studio中InflateException

API - 25

這是錯誤:

11-28 16:41:30.292 18444-18444/com.cs3340.gameoflife E/AndroidRuntime: FATAL EXCEPTION: main 
                    Process: com.cs3340.gameoflife, PID: 18444 
                    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.cs3340.gameoflife/com.cs3340.gameoflife.MainActivity}: android.view.InflateException: Binary XML file line #7: Binary XML file line #7: Error inflating class com.cs3340.gameoflife.GameView 
                     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2665) 
                     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2726) 
                     at android.app.ActivityThread.-wrap12(ActivityThread.java) 
                     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1477) 
                     at android.os.Handler.dispatchMessage(Handler.java:102) 
                     at android.os.Looper.loop(Looper.java:154) 
                     at android.app.ActivityThread.main(ActivityThread.java:6119) 
                     at java.lang.reflect.Method.invoke(Native Method) 
                     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886) 
                     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776) 
                    Caused by: android.view.InflateException: Binary XML file line #7: Binary XML file line #7: Error inflating class com.cs3340.gameoflife.GameView 
                    Caused by: android.view.InflateException: Binary XML file line #7: Error inflating class com.cs3340.gameoflife.GameView 
                    Caused by: java.lang.NoSuchMethodException: <init> [class android.content.Context, interface android.util.AttributeSet] 
                     at java.lang.Class.getConstructor0(Class.java:2204) 
                     at java.lang.Class.getConstructor(Class.java:1683) 
                     at android.view.LayoutInflater.createView(LayoutInflater.java:618) 
                     at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:787) 
                     at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:727) 
                     at android.view.LayoutInflater.rInflate(LayoutInflater.java:858) 
                     at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:821) 
                     at android.view.LayoutInflater.inflate(LayoutInflater.java:518) 
                     at android.view.LayoutInflater.inflate(LayoutInflater.java:426) 
                     at android.view.LayoutInflater.inflate(LayoutInflater.java:377) 
                     at com.android.internal.policy.PhoneWindow.setContentView(PhoneWindow.java:412) 
                     at android.app.Activity.setContentView(Activity.java:2414) 
                     at com.cs3340.gameoflife.MainActivity.onCreate(MainActivity.java:47) 
                     at android.app.Activity.performCreate(Activity.java:6679) 
                     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118) 
                     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2618) 
                     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2726) 
                     at android.app.ActivityThread.-wrap12(ActivityThread.java) 
                     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1477) 
                     at android.os.Handler.dispatchMessage(Handler.java:102) 
                     at android.os.Looper.loop(Looper.java:154) 
                     at android.app.ActivityThread.main(ActivityThread.java:6119) 
                     at java.lang.reflect.Method.invoke(Native Method) 
                     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886) 
                     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776) 

這是XML文件,它指:

<?xml version="1.0" encoding="utf-8"?> 
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
android:layout_width="fill_parent" 
android:layout_height="fill_parent" 
android:orientation="vertical" > 

<com.cs3340.gameoflife.GameView 
    android:id="@+id/gameView" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" /> 

</LinearLayout>" 

這是視圖本身:

package com.cs3340.gameoflife; 

import android.content.Context; 
import android.graphics.Canvas; 
import android.graphics.Color; 
import android.graphics.Paint; 
import android.util.AttributeSet; 
import android.view.MotionEvent; 
import android.view.View; 

/** 
* GameView is used to draw a single generation of the Game of Life 
*/ 
public class GameView extends View { 

/** 
* Variables used to calculate the size of the cells of the grid 
*/ 
private static final int CELL_SIZE = 40; 
private static final int HEIGHT = GameGlobal.getViewportHeight()/CELL_SIZE; 
private static final int WIDTH = GameGlobal.getViewportWidth()/CELL_SIZE; 

/** 
* Color of the grid 
*/ 
private Paint background = new Paint(); 

/** 
* Color of the cells 
*/ 
private Paint cellColor = new Paint(); 

/** 
* This represents the Cell Grid 
*/ 
private int [][] grid; 

/** 
* Flag to check if the game is running and prevent any changes to the grid 
*/ 
private static boolean isRunning = false; 

/** 
* Constructor 
* @param context 
*/ 
public GameView(Context context){ 
    super(context); 
    init(); 
} 

/** 
* Constructor helper method, initializes the varibales 
*/ 
private void init(){ 
    cellColor.setColor(Color.WHITE); 
    background.setColor(Color.BLACK); 
    initGrid(); 
} 

/** 
* Helper method creates the grid and initializes all cells to 0, ie "Dead" 
*/ 
private void initGrid(){ 
    grid = new int[HEIGHT][WIDTH]; 
    for(int i = 0; i < HEIGHT; i++){ 
     for(int j = 0; j < WIDTH; j++){ 
      grid[i][j] = 0; 
     } 
    } 
} 

/** 
* Draws the grid to the screen and sets the color 
* @param canvas 
*/ 
public void gameViewDraw(Canvas canvas){ 
    canvas.drawRect((float) 0, (float) 0, (float) getWidth(), 
      (float) getHeight(), background); 
} 

/** 
* This class handles the touch screen event of pressing on a cell 
* @param event 
*/ 
@Override 
public boolean dispatchTouchEvent(MotionEvent event){ 
    int x = (int) event.getX()/CELL_SIZE; 
    int y = (int) event.getY()/CELL_SIZE; 

    //if the cell is dead, make it alive and vice-versa 
    switch(event.getAction()){ 
     case MotionEvent.ACTION_DOWN: 
      if(grid[y][x] == 0){ 
       grid[y][x] = 1; 
      } 
      else{ 
       grid[y][x] = 0; 
      } 
     break; 
    } 
    //redraws the view thread 
    invalidate(); 
    return true; 
} 

/** 
* Mutator method for isRunning 
* @param running Boolean to set if the game is running or not 
*/ 
public void setIsRunning(boolean running){ 
    isRunning = running; 
} 

/** 
* Accessor method to return the cell grid 
* @return Game of Life cell grid 
*/ 
public int[][] getGrid(){ 
    return grid; 
} 

/** 
* Runs the game as an infinite loop 
*/ 
public void gameLoop(){ 

    new Thread(new Runnable(){ 

     /** 
     * Takes a 3x3 array around the current cell we are going to test for the next gen value 
     * @param squared 3x3 array around current cell 
     * @return nextGeneration state of the cell 
     */ 
     public int nextGeneration(int[][] squared){ 
      //value of the middle cell, ie, the cell we are testing for next gen 
      int currentGen = squared[1][1]; 

      /** 
      * calculates how many live cells are in the 3x3 array 
      */ 
      int alive = 0; 

      if(currentGen == 1){ 
       alive--; //removes 1 from the possible number of alive cells because we need only the surrounding cells 
      } 
      for(int i = 0; i < 3; i++){ 
       for(int j = 0; j < 3; j++){ 
        if(squared[i][j] == 1){ 
         alive++; 
        } 
       } 

      } 
      /** 
      * Applies the default Conways Game of Life rules: 
      * Alive Cell= > less than 2 or more than 3 live neighbours = dead 
      *    > 2 or 3 live neighbours = alive 
      * 
      * Dead Cell= > Exactly 3 live neighbours = alive 
      *   > Else = dead 
      */ 
      if(currentGen == 1){ 
       if(alive < 2 || alive > 3){ 
        return 0; 
       } else{ 
        return 1; 
       } 
      } else if(currentGen == 0){ 
       if(alive == 3){ 
        return 1; 
       } else{ 
        return 0; 
       } 
      } 
      //safety, never actually used 
      return 0; 
     } 


     @Override 
     public void run(){ 
      //initializing the array to be used in nextGeneration() 
      int[][] squared = new int [3][3]; 

      /** 
      * While the game is running 
      */ 
      while(isRunning){ 
       //temporary array to hold the new generation 
       int[][] nextGen = new int[HEIGHT][WIDTH]; 

       //This inserts every possible 3x3 grid from the original cell grid to be tested for the next generation values 
       //This loop also takes into account wrapping 
       for(int i = 0; i < HEIGHT; i++){ 
        for(int j = 0; i < WIDTH; j++){ 

         // row 1 
         if (i - 1 >= 0 && j - 1 >= 0) 
          squared[0][0] = grid[i - 1][j - 1]; 
         else if (i - 1 < 0 && j - 1 >= 0) 
          squared[0][0] = grid[HEIGHT - 1][j - 1]; 
         else if (i - 1 >= 0 && j - 1 < 0) 
          squared[0][0] = grid[j - 1][WIDTH - 1]; 
         else if (i - 1 < 0 && j - 1 < 0) 
          squared[0][0] = grid[HEIGHT - 1][WIDTH - 1]; 


         if (i - 1 >= 0) 
          squared[0][1] = grid[i - 1][j]; 
         else 
          squared[0][1] = grid[HEIGHT - 1][j]; 


         if (i - 1 >= 0 && j < WIDTH - 1) 
          squared[0][2] = grid[i - 1][j + 1]; 
         else if (i - 1 < 0 && j < WIDTH - 1) 
          squared[0][2] = grid[HEIGHT - 1][j + 1]; 
         else if (i - 1 >= 0 && j >= WIDTH - 1) 
          squared[0][2] = grid[i - 1][0]; 
         else if (i - 1 < 0 && j >= WIDTH - 1) 
          squared[0][2] = grid[HEIGHT - 1][0]; 

         // row 2 
         if (j - 1 >= 0) 
          squared[1][0] = grid[i][j - 1]; 
         else 
          squared[1][0] = grid[i][WIDTH - 1]; 


         squared[1][1] = grid[i][j]; 


         if (j < WIDTH - 1) 
          squared[1][2] = grid[i][j + 1]; 
         else 
          squared[1][2] = grid[i][0]; 

         // row 3 
         if (i < HEIGHT - 1 && j - 1 >= 0) 
          squared[2][0] = grid[i + 1][j - 1]; 
         else if (i >= HEIGHT - 1 && j - 1 >= 0) 
          squared[2][0] = grid[0][j - 1]; 
         else if (i < HEIGHT - 1 && j - 1 < 0) 
          squared[2][0] = grid[i + 1][WIDTH - 1]; 
         else if (i >= HEIGHT - 1 && j - 1 < 0) 
          squared[2][0] = grid[0][WIDTH - 1]; 


         if (i < HEIGHT - 1) 
          squared[2][1] = grid[i + 1][j]; 
         else 
          squared[2][1] = grid[0][j]; 


         if (i < HEIGHT - 1 && j < WIDTH - 1) 
          squared[2][2] = grid[i + 1][j + 1]; 
         else if (i >= HEIGHT - 1 && j < WIDTH - 1) 
          squared[2][2] = grid[0][j + 1]; 
         else if (i < HEIGHT - 1 && j >= WIDTH - 1) 
          squared[2][2] = grid[i + 1][0]; 
         else if (i >= HEIGHT - 1 && j >= WIDTH - 1) 
          squared[2][2] = grid[0][0]; 


         nextGen[i][j] = nextGeneration(squared); 

        } 
       } 
      } 

     } 

    }).start(); 


    } 

} 

謝謝s

回答

2

您的GameView需要雙參數構造函數,因爲這是LayoutInflater用於從XML構建視圖層次結構的構造函數。

public GameView(Context context, AttributeSet attrs) { 
    super(context, attrs); 
    init(); 
} 
+0

問題解決了,非常感謝你! –