我试图用单例模式编写代码。
这是我的MainActivity。
public class MainActivity extends AppCompatActivity {
public static MainActivity activity;
public TouchSensor touchSensor;
public SurfaceViewThread surfaceViewThread;
public TriggerChecker triggerChecker;
public Physics physics;
//public static Handler mHandler = new Handler();
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
activity = this;
surfaceViewThread = SurfaceViewThread.getInstance();
touchSensor = TouchSensor.getInstance();
triggerChecker = TriggerChecker.getInstance();
physics = Physics.getInstance();
touchSensor.start();
triggerChecker.start();
physics.start();
//surfaceViewThread is already started.
activity.setContentView(surfaceViewThread);
}
这是我尝试用单例模式编写的代码。
public class SurfaceViewThread extends SurfaceView implements Runnable, SurfaceHolder.Callback {
private static SurfaceViewThread surfaceViewThread = new SurfaceViewThread();
private static Camera camera;
private SurfaceHolder holder;
private Thread thread;
private boolean run;
private Vector<ObjectGraphic> objects;
private Vector<Graphic> UIs;
private ObjectGraphic field;
private Vector<ObjectGraphic> draws;
private ComponentMessage componentMessage;
public static SurfaceViewThread getInstance()
{
if(surfaceViewThread == null)
surfaceViewThread = new SurfaceViewThread();
return surfaceViewThread;
}
private SurfaceViewThread()
{
super(activity.getApplicationContext());
camera = new Camera();
getHolder().addCallback(this);
holder = getHolder();
objects = new Vector<>();
UIs = new Vector<>();
draws = new Vector<>();
run = false;
componentMessage = new ComponentMessage();
}
当我构建此代码时,Camera类被NullPointException崩溃。
public class Camera extends GameObject {
private Rect area;
private int sight;
private int maxSight = 50;
private int minSight = 10;
private int[] fieldOfView;//{vertical, horizontal}
private int[] maxFieldOfView = new int[] { 60, 45 };
private int[] minFieldOfView = new int[] { 10, 10 };
public Camera()
{
super();
area = new Rect();
this.fieldOfView = new int[] { 60, 45 };
objectMatrix.Rotate(objectMatrix.xVector(), Math.toRadians(-45));
setDisplayVector();
}
private void setSight()
{
double angle = Math.PI/2 - Math.acos(new Common_Math.Matrix1X4(0, 1, 0, 0).Inner(objectMatrix.zVector().Invert()));
if(angle < 0 && angle > - Math.PI/2) {
double t = -objectMatrix.qVector().getY() / objectMatrix.zVector().getY();
int x = (int) (objectMatrix.zVector().getX() * t + objectMatrix.qVector().getX());
int z = (int) (objectMatrix.zVector().getZ() * t + objectMatrix.qVector().getZ());
sight = (int)Math.sqrt(Math.pow((x - objectMatrix.qVector().getX()), 2) + Math.pow((objectMatrix.qVector().getY()), 2) + Math.pow((z - objectMatrix.qVector().getZ()), 2));
if(sight < minSight)
sight = minSight;
}
else
{
sight = maxSight;
}
}
private void setDisplayVector()
{
setSight();
Common_Math.Matrix1X4 upVector, downVector, leftVector, rightVector;
Common_Math.Matrix1X4 zVector = objectMatrix.zVector();
upVector = zVector.Rotate(objectMatrix.xVector(), fieldOfView[0]);
downVector = zVector.Rotate(objectMatrix.xVector(), -fieldOfView[0]);
leftVector = zVector.Rotate(objectMatrix.yVector(), fieldOfView[1]);
rightVector = zVector.Rotate(objectMatrix.yVector(), -fieldOfView[1]);
double angle = Math.PI/2 - Math.acos(new Common_Math.Matrix1X4(0, 1, 0, 0).Inner(objectMatrix.zVector().Invert()));
upVector = upVector.Scaled((int)(Math.abs(objectMatrix.qVector().getY() * Math.tan(angle + fieldOfView[0]))));
downVector = downVector.Scaled((int)(Math.abs(objectMatrix.qVector().getY() * Math.tan(angle - fieldOfView[0]))));
leftVector = leftVector.Scaled((int)(sight * Math.asin(fieldOfView[1])));
rightVector = rightVector.Scaled((int)(sight * Math.asin(fieldOfView[1])));
area.left = (int) objectMatrix.qVector().Add(leftVector).getX();
area.top = (int) objectMatrix.qVector().Add(upVector).getY();
area.right = (int) objectMatrix.qVector().Add(rightVector).getX();
area.bottom = (int) objectMatrix.qVector().Add(downVector).getY();
}
这是GameObject类
public class GameObject {
protected GameObject upperGameObject;//if upperGameObject is null, this GameObject is parent GameObject.
protected Common_Math.Matrix4X4 objectMatrix;
private Vector<SeaWeedComponent> componentVector;
public GameObject()
{
objectMatrix = new Common_Math.Matrix4X4();
AllocatePhysicsSpace();
componentVector = new Vector<>();
}
和Matrix4x4类
public static class Matrix4X4
{
private Matrix1X4 xVector, yVector, zVector, qVector;
public Matrix4X4() {
xVector = new Matrix1X4(1, 0, 0, 0);
yVector = new Matrix1X4(0, 1, 0, 0);
zVector = new Matrix1X4(0, 0, 1, 0);
qVector = new Matrix1X4(0, 0, 0, 1);
}
所以我检查了一个断点,看看为什么会发生这种情况,但是当我调试这个时,每个变量都停留在“收集数据......”并且没有任何反应。甚至debuger的反应也很慢。
我猜不出为什么会这样。我的代码有什么问题吗?我怎样才能看到变量?
答案 0 :(得分:2)
不确定这应该是评论还是答案......
我在一个完全不同的上下文中看到了同样的问题,它“以某种方式”与使用线程有关。 似乎当调试器试图获取一个值并且需要运行与另一个线程相关联的东西时,它就会死锁。
在我的情况下,我有一个javascript引擎,当我需要执行JS时,在非ui线程上调用它。如果我在任何地方都有变量,例如JSObject的子类,调试器锁定。
我发现解决这个问题的唯一方法就是明智地记录和设置我的断点。
检查代码在访问变量时是否遇到任何锁定或同步语句,这可能是您的原因。
答案 1 :(得分:0)
GameObject.class做什么?您的Camera类正在扩展GameObject.class并在构造函数中调用super()。跳过调试器并使用经典日志记录代替在设置变量之前打印出来。
Singleton没有做任何特别的事情,除了将自己保持为单个实例,不知道Android Studio Debugger如何处理它们但它不应该有问题。当您尝试实例化Camera.class时,会出现NULL。
在实例化Camera()
时尝试捕获NullPointertry {
Camera cam = new Camera();
} catch (NullPointerException e) {
e.printStackTrace();
}
堆栈跟踪应该告诉你NullPointer在代码中的位置
答案 2 :(得分:0)
我在创建一个新的虚拟设备来复制我的手机后遇到了同样的问题。它已经工作了一段时间然后每次我尝试调试它在它出现的第一个断点处停止工作并且正在“收集数据......”
我刚刚切换回原始虚拟设备(5.1 WVGA API 25),调试器开始按照提示进行操作。
我切换到新的虚拟设备,问题就消失了。
可能与我创建的无限循环有关,该循环将活动快照抛出但不太确定。如果再次发生会更新。