Android模拟器在使用并发时崩溃

时间:2010-12-13 20:52:41

标签: android concurrency android-emulator

这个问题是关于使用Java编程语言的Google Android SDK。

我的问题可以归结为:为什么这段代码会导致android模拟器崩溃?

我一直在为与游戏应用程序设置不同线程相关的并发性进行几天的摔跤。 我做了很多变化,但都失败了。此时,我只想获得基本的并发设置。最糟糕的是,它是模拟器崩溃,所以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){}。请记住,这是一个表明问题的人为例子。在我自己的代码中,我按照文档中的描述执行生命周期活动。问题是模拟器在无限循环中经过一段时间后会崩溃,无论你是否有中断条件。

1 个答案:

答案 0 :(得分:0)

您可能想要查看AsyncTask。这里有很棒的文章:http://android-developers.blogspot.com/2009/05/painless-threading.html