Java を使用したマルチスレッドは初めてです。私はいくつかの調査を行い、チュートリアルを読み、テストを行いましたが、この問題で立ち往生しています。基本的に、私はゲームのスケルトンをセットアップしています。メソッドを含むスレッド クラスであるメイン アクティビティ クラスが必要で、低速な操作 (ファイルの読み取りとコンテンツのバッファへのアンパック) を実行し、スレッドが必要です。 UI操作に反応するゲームループです。
まず、別のスレッドをインスタンス化して開始するメイン アクティビティ クラスがあります。
public class ExperimentsActivity extends Activity {
// This is just a container class with some member data such as ByteBuffers and arrays
TestClass tclass = new TestClass(this);
// Main looping thread
MainLoopThread loop;
Thread mainLoop;
// Start the main looping thread which will trigger the engine's operations
loop = new MainLoopThread(tclass);
mainLoop = new Thread(loop);
mainLoop.start();
loop.setRunning(true);
(...)
}
次に、MainLoopThread
ゲーム ロジックのスレッドを実装するクラスがあります。
public class MainLoopThread implements Runnable {
public boolean running;
private TestClass baseData;
// Thread for data loading/unpacking ( CLASS DEFINITION BELOW )
GFXUnpack dataUnpack;
Thread dataUnpackThread;
public MainLoopThread( TestClass testClassStructure ) {
running = false;
baseData = testClassStructure;
}
public void setRunning ( boolean run ) {
if ( run == true )
{
// Launch the thread which manages loading and unpacking graphics
dataUnpack = new GFXUnpack(baseData.filepack[0]);
dataUnpackThread = new Thread(dataUnpack);
dataUnpackThread.start();
dataUnpack.setRunning(true);
fileOpened = false;
// Open the GFX packet file
try {
synchronized (this) {
dataUnpack.setOperation(2);
Log.d("MainLoopThread", "File opening : waiting...");
while ( dataUnpack.fileOpened == false ) {
wait();
}
Log.d("MainLoopThread", "File opening wait completed");
}
if ( dataUnpack.outCode == -1 )
Log.d("MainLoopThread", "File opening error !!");
else fileOpened = true;
Log.d("MainLoopThread", "File opening completed");
}
catch ( Exception exp ) {
Log.d("MainLoopThread", "File opening code exception !!" + exp);
}
}
else if ( dataUnpack.running == true ) dataUnpack.setRunning(false); running = run;
}
// ------------------------------------
// Here is the main looping thread. All the events related to loading
// and unpacking graphics go here
public void run() {
while (running) {
synchronized (this) {
// ------ Read a GFX packet and update texture pixels
if ( fileOpened == true ) {
try {
// ( Do some stuff... )
wait();
} catch ( Exception exp ) {
Log.d("MainLoopThread", "Exception thrown !! " + exp );
}
}
} // ( Thread-out code removed. Anyway, it never passed here )
}
そして最後に、GFXUnpack
SD カード上のファイルを開くコードを含むスレッド クラスが、SD カード内のものを読み取り、バッファに書き込みます。
public class GFXUnpack implements Runnable {
// -------------
public boolean running = false;
private Filedata fdata;
private int operation = 0, parameter = 0;
public boolean fileOpened;
public int outCode; // Used to signal the caller about the outcome of the operation
// ------------------------------
public GFXUnpack ( Filedata packetDataStructure ) {
this.fdata = packetDataStructure;
}
// --------
public void setRunning ( boolean run ) {
running = run; operation = 0; fileOpened = false;
outCode = 0; parameter = 0;
}
// --------
public void setOperation ( int op ) {
operation = op;
}
// ---
public void setOperation ( int op, int parm ) {
operation = op;
parameter = parm;
}
// ---------
public synchronized void run() {
while (running) {
try {
switch ( operation ) {
case ( 2 ) : // Open the gfx data file
( ...do stuff... )
break;
}
// ---------
try {
( ...Do some stuff here... )
Log.d("GFXUnpack", "Mapping file");
( ...Do some stuff here... )
Log.d("GFXUnpack", "Mapped file");
fileOpened = true;
outCode = 1;
} catch ( Exception e ) {
Log.d("GFXUnpack", "File opening exception !! " + e);
outCode = -1;
}
finally {
operation = 0; parameter = 0;
notifyAll();
Log.d("GFXUnpack", "Notified file opening");
}
}
break;
// ----------------
}
// ----- Other cases here...
} finally {
}
}
}
上記を実行すると、デバッガーの出力は次のようになります。
MainLoopThread ファイルを開く: 待機中...
GFXUnpack マッピング ファイル
GFXUnpack マップされたファイル
GFXUnpack 通知されたファイルを開く
その後、アプリがハングし、強制終了する必要があります。(ブロック内の)notifyAll()
のrun()
メソッドを呼び出すので、呼び出し元のスレッド (MainLoopThread) が続行され、デバッガー メッセージ 'File opening completed' が表示されると思いましたが、代わりにアプリがハングします。GFXunpack
finally{}
なぜこれが起こっているのか、誰にもアイデアがありますか?