【问题标题】:Android emulator crashes while using concurrencyAndroid 模拟器在使用并发时崩溃
【发布时间】: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


【解决方案1】:

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

【讨论】:

  • 虽然 AsyncTasks 非常有用,但它们并不是所有线程问题的最终解决方案。有时线程是正确的方法,在这种情况下,AsyncTasks 不会很有帮助。
猜你喜欢
  • 2015-04-29
  • 1970-01-01
  • 2012-11-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多