【发布时间】:2010-12-13 20:52:40
【问题描述】:
这个问题是关于在 Java 编程语言中使用 Google Android SDK。
我的问题可以归结为:为什么这段代码会导致安卓模拟器崩溃?
几天来,我一直在为与为游戏应用设置不同线程相关的并发问题而苦苦挣扎。 我做了很多变化,但都失败了。在这一点上,我只想进行基本的并发设置。最糟糕的是,是模拟器崩溃了,所以 DDMS 什么也没有报告;因此,我对问题出在哪里一无所知。
以下代码显示了一个活动(Main 类),它调用了 SceneManager 类,它创建了一个用于游戏逻辑内容的线程。第三个类,StatusChannel,用于(将)用于在不同线程之间传递状态信息(最终,还会有一个 OpenGL 渲染线程)。
模拟器在不同的时间崩溃。它可能会运行 20 秒或 5 分钟。
Activity 类中的 setContentView(R.layout.main) 就是 Eclipse 创建的设置基本布局。
我已经注释掉了Node的用法(在Activity类中创建,在SceneManager中访问)
我已经安装了 sdk 版本 1.5 到 2.3 -- 当前的应用程序是针对 2.1 的
这个问题与 SceneManager 类有关。我特别怀疑 run() 方法。
这里有 3 个类。
对不起,代码长度。
public class Main extends Activity {
private SceneManager mSceneManager;
private volatile Node mSceneGraph = new Node();
private volatile Status mStatusChannel = new Status();
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
Log.d("-- Main", "onCreate()");
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// Holds the scene assets, such as the stage,
// the agents, camera, etc.
mSceneManager = new SceneManager(mSceneGraph, mStatusChannel);
mSceneManager.onCreate();
}
@Override
protected void onResume() {
Log.d("-- Main", "onResume()");
super.onResume();
mSceneManager.onResume();
}
@Override
protected void onPause() {
Log.d("-- Main", "onPause()");
super.onPause();
mSceneManager.onPause();
}
@Override
protected void onDestroy() {
Log.d("-- Main", "onDestroy()");
super.onDestroy();
mSceneManager.onDestroy();
}
}
public class SceneManager implements Runnable{
private Thread mThread;
private volatile Status mStatusChannel;
private volatile Node mSceneGraph;
private volatile long mMillis = 0;
private volatile PrepareVisitor mPrepareVisitor;
private volatile int mStatus = Status.UNKNOWN_STATUS;
SceneManager(Node sceneGraph, Status statusChannel) {
mPrepareVisitor = new PrepareVisitor();
mStatusChannel = statusChannel;
mSceneGraph = sceneGraph;
mMillis = SystemClock.uptimeMillis();
mThread = new Thread(this);
mThread.setName("LogicThread");
mStatusChannel.setSceneManagerStatus(Status.READY_STATUS);
}
public void onCreate() {
Log.d("-- SceneManager", "onCreate()...");
// This will start the thread in a paused state.
mThread.start();
}
public void onResume() {
Log.d("-- SceneManager", "onResume()...");
// Unpause the status manager, if it is currently paused.
if (mStatusChannel.getSceneManagerStatus() == Status.PAUSED_STATUS) {
mStatusChannel.setSceneManagerStatus(Status.READY_STATUS);
}
}
public void onPause() {
Log.d("-- SceneManager", "onPause()...");
if (mStatusChannel.getSceneManagerStatus() != Status.UNKNOWN_STATUS) {
mStatusChannel.setSceneManagerStatus(Status.PAUSED_STATUS);
}
}
public void onDestroy() {
mStatusChannel.setSceneManagerStatus(Status.QUIT_STATUS);
try {
mThread.join();
}
catch (InterruptedException e) {
Log.d("-- SceneManager", "InterruptedException");
}
}
/**
* This method should not be called by clients of this class.
*/
@Override
public void run() {
Log.d("-- SceneManager", "Called...");
// Main logic loop.
outer: while (true) {
// How much time has elapsed since last call.
long timeDelta = SystemClock.uptimeMillis() - mMillis;
switch (mStatus) {
case Status.READY_STATUS:
//mPrepareVisitor.go(mSceneGraph, timeDelta);
break;
case Status.PAUSED_STATUS:
break;
case Status.QUIT_STATUS:
break outer;
case Status.UNKNOWN_STATUS:
int renderStatus = mStatusChannel.getRendererStatus();
if (renderStatus == Status.READY_STATUS) {
mStatusChannel.setSceneManagerStatus(Status.READY_STATUS);
}
break;
}
mStatus = mStatusChannel.getSceneManagerStatus();
// Update the time.
mMillis = SystemClock.uptimeMillis();
}
}
}
public class Status {
/* Generic Statuses */
public final static int UNKNOWN_STATUS = 0;
public final static int READY_STATUS = 1;
public final static int PAUSED_STATUS = 2;
public final static int QUIT_STATUS = 3;
/* Current statuses values */
private int mSceneManagerStatus = UNKNOWN_STATUS ;
private int mRendererStatus = UNKNOWN_STATUS ;
public synchronized int getSceneManagerStatus() {
return mSceneManagerStatus;
}
public synchronized int getRendererStatus() {
return mRendererStatus;
}
public synchronized void setSceneManagerStatus(int status) {
mSceneManagerStatus = status;
}
public synchronized void setRendererStatus(int status) {
mRendererStatus = status;
}
}
-- 编辑--
This issue happens even with something as simple as this:
public class ThreadActivity extends Activity {
private Booboo mBooboo;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mBooboo = new Booboo();
mBooboo.onCreate();
}
}
public class Booboo implements Runnable {
private Thread mThread;
Booboo() {
mThread = new Thread(this, "SceneManagerThread");
}
public void onCreate() {
Log.d("Booboo", "Thread started");
mThread.start();
}
@Override
public void run() {
while (true) {}
}
}
我知道第一反应是说这是 while(true){}。请记住,这是一个显示问题的人为示例。在我自己的代码中,我按照文档中的描述执行生命周期活动。问题是模拟器在这样的无限循环中一段时间后崩溃,无论您是否有中断条件。
【问题讨论】:
-
当您说模拟器崩溃时,您是指模拟器崩溃还是您的应用程序崩溃,有任何崩溃日志?
标签: android concurrency android-emulator