我对Android编码很新,我正在尝试制作一个简单的游戏,其中有不同的方块可以四处移动并相互重叠。
现在我只是试图制作一堆不同的视图,这些视图在某些地方有正方形,我以后可以动画并移动到彼此之上。我遇到了一个问题,我得到以下错误:
06-08 16:18:31.407: E/AndroidRuntime(16612): FATAL EXCEPTION: main
06-08 16:18:31.407: E/AndroidRuntime(16612): Process: com.example.drawable, PID: 16612
06-08 16:18:31.407: E/AndroidRuntime(16612): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.drawable/com.example.drawable.MainActivity}: java.lang.NullPointerException
06-08 16:18:31.407: E/AndroidRuntime(16612): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2282)
06-08 16:18:31.407: E/AndroidRuntime(16612): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2340)
06-08 16:18:31.407: E/AndroidRuntime(16612): at android.app.ActivityThread.access$800(ActivityThread.java:157)
06-08 16:18:31.407: E/AndroidRuntime(16612): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1247)
06-08 16:18:31.407: E/AndroidRuntime(16612): at android.os.Handler.dispatchMessage(Handler.java:102)
06-08 16:18:31.407: E/AndroidRuntime(16612): at android.os.Looper.loop(Looper.java:157)
06-08 16:18:31.407: E/AndroidRuntime(16612): at android.app.ActivityThread.main(ActivityThread.java:5293)
06-08 16:18:31.407: E/AndroidRuntime(16612): at java.lang.reflect.Method.invokeNative(Native Method)
06-08 16:18:31.407: E/AndroidRuntime(16612): at java.lang.reflect.Method.invoke(Method.java:515)
06-08 16:18:31.407: E/AndroidRuntime(16612): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1265)
06-08 16:18:31.407: E/AndroidRuntime(16612): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1081)
06-08 16:18:31.407: E/AndroidRuntime(16612): at dalvik.system.NativeStart.main(Native Method)
06-08 16:18:31.407: E/AndroidRuntime(16612): Caused by: java.lang.NullPointerException
06-08 16:18:31.407: E/AndroidRuntime(16612): at com.example.drawable.Grid.addRandomSquare(Grid.java:54)
06-08 16:18:31.407: E/AndroidRuntime(16612): at com.example.drawable.Grid.<init>(Grid.java:30)
06-08 16:18:31.407: E/AndroidRuntime(16612): at com.example.drawable.MyViewGroup.<init>(MyViewGroup.java:26)
06-08 16:18:31.407: E/AndroidRuntime(16612): at com.example.drawable.MainActivity.onCreate(MainActivity.java:35)
06-08 16:18:31.407: E/AndroidRuntime(16612): at android.app.Activity.performCreate(Activity.java:5389)
06-08 16:18:31.407: E/AndroidRuntime(16612): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1105)
06-08 16:18:31.407: E/AndroidRuntime(16612): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2246)
06-08 16:18:31.407: E/AndroidRuntime(16612): ... 11 more
MainActivity:
public class MainActivity extends Activity {
public static MyViewGroup vgrp;
public static boolean rfr;
int i;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
requestWindowFeature(Window.FEATURE_NO_TITLE);
vgrp = new MyViewGroup(getApplicationContext());
setContentView(vgrp);
}
@Override
protected void onPause() {
super.onPause();
}
}
的ViewGroup:
public class MyViewGroup extends ViewGroup{
public int direction;
public float touchx;
public float touchy;
public float xprev;
public float yprev;
public float xnew;
public float ynew;
public float dx;
public float dy;
public int in;
private Grid grid;
public MyViewGroup(Context context) {
super(context);
grid = new Grid(4);
System.out.println("hellloooooooo"); //4
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
// TODO Auto-generated method stub
}
public void newRectangleAt(int x, int y){
Log.d("com.example.drawable","coordinates" + x + ", "+ y + " are free");
x+=1;
y+=1;
x*=GraphicsDriver.scale;
y*=GraphicsDriver.scale;
SquareView sq = new SquareView(getContext());
sq.setPos(x, y);
GraphicsDriver.graphicsGrid.add(sq);
}
@SuppressLint("NewApi")
public boolean onTouchEvent(MotionEvent ev){
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN: {
xprev = ev.getX();
yprev = ev.getY();
return true;
}
case MotionEvent.ACTION_MOVE:
{
return false;
}
case MotionEvent.ACTION_UP:
{
Log.d("com.example.drawable","action completed");
xnew = ev.getX();
ynew = ev.getY();
dx=xnew-xprev;
dy=ynew-yprev;
if((dx < 10) && (Math.abs(dx) > Math.abs(dy)))
direction = Grid.LEFT;
else if(( dx > 10) && (Math.abs(dx) > Math.abs(dy)))
direction = Grid.RIGHT;
else if((dy > 10) && (Math.abs(dy) > Math.abs(dx)))
direction = Grid.DOWN;
grid.parseGrid(direction);
return false;
}
}
invalidate();
return true;
}
}
Grid.class:
public class Grid {
private Space[][] grid;
public final static int DOWN = 0;
public final static int RIGHT = 1;
public final static int LEFT = -1;
private GraphicsDriver gd;
//constructs grid of given size
public Grid(int size){
int s = size;
grid = new Space[s][s*2];
for(int y = 0; y < grid[0].length; y++)
for(int x = 0; x < grid.length; x++)
grid[x][y] = new Space();
gd = new GraphicsDriver(this);
this.addRandomSquare();
this.addRandomSquare();
}
public Space[][] getGrid(){
return this.grid;
}
public GraphicsDriver getGraphicsDriver(){
return this.gd;
}
public void addRandomSquare(){
int x = (int)(Math.random()*grid.length-.001);
boolean b = true;
for(int y = grid[0].length-1 ; y >= 0 ; y--)
if(b)
if( grid[x][y].isFree()==true){
Log.d("com.example.drawable","coordinates" + x + ", "+ y + " are free");
grid[x][y].placeSquare(new Square());
Log.d("com.example.drawable","coordinates" + x + ", "+ y + " are free");
MainActivity.vgrp.newRectangleAt(x,y);
Log.d("com.example.drawable","coordinates" + x + ", "+ y + " are free");
b=false;
}
}
//returns the space in the given direction -- useful to check space availability
public Space getAdjacentSpace(int x, int y, int direction){
Space ret;
ret = null;
try{
if(direction == DOWN && grid[x][y+1] != null){
ret = grid[x][y+1];}
if(direction == RIGHT && grid[x+1][y] != null){
ret = grid[x+1][y];}
if(direction == LEFT && grid[x-1][y] != null){
ret = grid[x-1][y];}
}
catch(ArrayIndexOutOfBoundsException e){
ret = null;
}
return ret;
}
public void parseGrid(int direction){
if(direction == DOWN)
for(int y = grid[0].length-1; y >= 0; y--)
for(int x = 0; x < grid.length; x++)
attemptMove(x,y,direction);
if(direction == LEFT)
for(int x = 1; x < grid.length; x++)
for(int y = grid[0].length-1; y >= 0; y--)
attemptMove(x,y,direction);
if(direction == RIGHT)
for(int x = grid.length-2; x >= 0 ; x--)
for(int y = grid[0].length-1; y >= 0; y--)
attemptMove(x,y,direction);
addRandomSquare();
GraphicsDriver.drawGrid();
Log.d("com.example.drawable","parsed grid");
}
public Space getSpace(int x, int y){
return grid[x][y];
}
//tries to move the place of the square in the direction swiped
public void attemptMove(int x, int y, int direction){
try{
if ((y == (grid[0].length-1)) && (direction==DOWN) && (bottomRowCollapsible())){
grid[x][y].removeSquare();
}
else if(!getSpace(x,y).isFree() && getAdjacentSpace(x,y,direction).isFree()){
moveSquare(x,y,direction);
}
else if (getSpace(x,y).getSquareShade() == getAdjacentSpace(x,y,direction).getSquareShade()){
grid[x][y].getSquare().setShade();
moveSquare(x,y,direction);
}
}
catch(NullPointerException e){}
}
//checks if the bottom row is full of the highest shade
private boolean bottomRowCollapsible() {
boolean b = true;
for(int x = grid.length-1; x >=0; x-- )
if(grid[x][grid[0].length-1].getSquareShade()!=6) b = false;
return b;
}
public void moveSquare(int x, int y, int direction){
Square sqr = grid[x][y].removeSquare();
Log.d("com.example.drawable","square removed at " + (x+1)+", " +(y+1));
if(direction == DOWN && y != 0){
grid[x][y+1].placeSquare(sqr);
}
if(direction == RIGHT && (x != grid.length-1)){
grid[x+1][y].placeSquare(sqr);
Log.d("com.example.drawable","square placed at " + (x+2) + ", "+ (y+1));
}
if(direction == LEFT && x != 0){
grid[x-1][y].placeSquare(sqr);
}
}
}
SquareView.class:
package com.example.drawable;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
public class SquareView extends View{
private Paint paint;
int x;
int y;
final int size = 15;
public SquareView(Context context){
super(context);
paint = new Paint();
paint.setColor(Color.BLUE);
paint.setAlpha(20);
}
public void setPos(int x, int y){
this.x=x;
this.y=y;
}
public void onDraw(Canvas canvas){
canvas.drawColor(Color.TRANSPARENT);
canvas.drawRect(x-size, y+size, x+size, y-size, paint);
}
}
GraphicsDriver.class:
@SuppressWarnings("unused")
public class GraphicsDriver {
public final int size = 50;
public final static int scale = 220;
public static ArrayList<SquareView> graphicsGrid;
private Paint paint;
public GraphicsDriver(Grid gr){
graphicsGrid = new ArrayList<SquareView>();
paint = new Paint();
paint.setColor(Color.BLUE);
}
public static void drawGrid(){
for(SquareView square: graphicsGrid){
MainActivity.vgrp.addView(square);
}
}
mainactivity.xml文件:
<?xml version="1.0" encoding="utf-8"?>
<com.example.drawable.MyViewGroup xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/screen" android:orientation="vertical"
android:layout_width="fill_parent" android:layout_height="fill_parent">
<com.exammple.drawable.SquareView android:id="@+id/SquareView" android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
</com.example.drawable.MyViewGroup>
任何帮助都将非常感谢!!
答案 0 :(得分:0)
它来自那条线,这是:
MainActivity.vgrp.newRectangleAt(x,y);
检查调用堆栈。在onCreate()
中,您有:
vgrp = new MyViewGroup(getApplicationContext());
但是,MyViewGroup
的构造函数会调用new Grid()
,然后调用addRandomSquare()
。这意味着当addRandomSquare()
执行时,vgrp
静态字段尚未设置。因此,NullPointerException。
请查看What is a stack trace, and how can I use it to debug my application errors?
顺便说一句,对Views进行静态引用是一个非常糟糕的主意,因为(1)它会导致内存泄漏,(2)如果你创建了这个activity的第二个实例,它们都会指向同一个{ {1}}(即最后创建的那个)。