2010-12-13 15 views
1

この質問は、Javaプログラミング言語でGoogle Android SDKを使用することについてです。同時実行性を使用している間にAndroidエミュレータがクラッシュする

私の質問は次のようになります:なぜこのコードがアンドロイドエミュレータをクラッシュさせるのですか?

私は数日間、ゲームアプリケーション用に異なるスレッドを設定することに関連して並行処理をしています。 私は多くのバリエーションを作っていますが、すべてが失敗しました。現時点では、基本的な同時セットアップを実行したいだけです。最悪の部分はクラッシュするエミュレータだから、DDMSは何も報告しません。だから私は問題がどこにあるのかわからない。

次のコードは、ゲームロジック用に使用されるスレッドを作成する、SceneManagerクラスを呼び出すアクティビティ(クラスMain)を示しています。 3番目のクラスStatusChannelは、異なるスレッド間でステータス情報をやりとりするために使用されます(最終的には、OpenGLレンダリングスレッドもあります)。

異なる時刻にエミュレータがクラッシュします。 20秒間または5分間実行することができます。

アクティビティクラスのsetContentView(R.layout.main)は、Eclipseが作成する基本レイアウトのみを設定します。

私は2.3経由SDKバージョン1.5をインストールしたノード(Activityクラスで作成してのSceneManagerでアクセス)

の使用をコメントアウトしました - 現在のアプリは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; 
} 
} 

- EDIT -

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) {} 
     } 
} 

Iは最初の反応は、それが(TRUE){}ながらだと言うことは知っています。これが問題を示すために考案された例であることを覚えておいてください。私自身のコードでは、ドキュメントに記述されているライフサイクル活動を行っています。問題は、あなたがブレーク条件を持っているかどうかに関係なく、エミュレータがそのような無限ループでしばらくしてクラッシュすることです。

+1

エミュレータがクラッシュすると、エミュレータがクラッシュしたり、アプリケーションがクラッシュしたり、クラッシュのログが発生したりすることはありますか? – aronp

答えて

0

おそらく、AsyncTaskを調べたいと思うかもしれません。 http://android-developers.blogspot.com/2009/05/painless-threading.html

+0

AsyncTasksは非常に便利ですが、すべてのスレッド問題に対する最終的な答えではありません。時にはスレッドが正しい方法です。この場合、AsyncTasksはあまり役に立ちません。 – kabuko

関連する問題