7

この数か月間、私は汎用性の高いリアルタイム ゲーム エンジンを開発してきました。多くのことを学びましたが、アプリケーションのライフ サイクルに関しては、まだ非常にナイーブだと感じています。具体的には、ユーザーがバックグラウンドにシャッフルしてから適切に再開できるアクティビティを実装しようとしています。

私の現在のアーキテクチャは次のとおりです。インテントを使用してリアルタイムのゲーム アクティビティを作成できる XML メニュー ランチャー アクティビティがあります。このゲーム アクティビティの関連データは、静的データ構造と変数を通じて参照されます。Game アクティビティは、SurfaceView オブジェクトの onSurfaceCreate() コールバックでワーカー スレッドを作成します。

ユーザーが戻るボタンを押すと、アクティビティは破棄され、ランチャー アクティビティの XML メニューに戻されます。いいよ、とりあえず。ユーザーがホーム ボタンを押すと、Activity がバックグラウンドに送信されます。わかりました。バックグラウンドに送信された後、ユーザーがゲームアクティビティに戻る方法を見つけようとすると、問題が発生します。ユーザーがランチャー アイコンに触れると、ゲームが破棄され、メニューが再起動されます。また、ユーザーがタスク マネージャーからゲームを再開すると、onSurfaceCreate() コールバックが起動し、ワーカー スレッドが開始されますが、ゲームはフリーズします。

それで、私は2つの質問があります。まず、ゲームを再起動するのではなく、ランチャー アイコンからアクティビティを再開するにはどうすればよいですか? 次に、アクティビティを再開するときに、ゲーム データを保持しながらワーカー スレッドを再開するには、どのようなアクションが必要ですか?

ありがとう!

編集:リクエストにより、以下のコードを含めています。私の onSurfaceCreate は少し複雑です。別のスレッドにメッセージを送信し、別のスレッドがコールバックを実装します。Game アクティビティが再開されると、この実装関数が起動することを確認しました。

protected void surfaceCreate()
{
    Log.e(TAG, "surfaceCreate");

    Thread gameThread = createGameThread();
    gameThread.start();
}


protected final void onResume()
{
    super.onResume();

    resume();
}

protected final void onPause()
{
    super.onPause();

    pause();
}

これらの不可解な pause() および resume() メソッドは、一部のゲーム ロジックが実行されないようにするブール変数を設定するだけであり、ループを継続する必要があるワーカー スレッドを妨げることはありません。

編集:私の最初の(小さいながらも)問題を解決してくれたMohammadに感謝します。USB で IDE に接続されていない場合、ランチャー アイコンの動作が異なることが判明しました。2 番目の問題は未解決のままです。

編集:すべての作業! 2 番目の問題は、私のコードに固有の問題であることが判明しました。申し訳ありません。この質問が、ランチャーと IDE を扱う人にとって引き続き役立つことを願っています。

4

1 に答える 1

5

この投稿には、複数の考えられる問題/解決策が記載されています。これには、アクティビティのライフサイクルlaunchMode 設定の誤解が含まれます。

まず、ゲームを再起動するのではなく、ランチャー アイコンからアクティビティを再開するにはどうすればよいですか?

onResume()およびonPause()メソッドの定義が欠落している可能性が最も高いです。例はここにあります:

http://developer.android.com/training/basics/activity-lifecycle/pausing.html

API から直接:

onPause() アクティビティがバックグラウンドに移行するときにアクティビティ ライフサイクルの一部として呼び出されますが、(まだ) 強制終了されていません。

onResume()アクティビティがユーザーとの対話を開始するために、onRestoreInstanceState(Bundle)、onRestart()、または onPause() の後に呼び出されます。

Android アプリケーションをコーディングするときは、次のフローを理解して従う必要があります。

Android アクティビティのライフサイクルを確認してください。

http://developer.android.com/reference/android/app/Activity.html

あなたの問題に関する 1 つの理論は、(ホーム ボタンを押すことによって) onStop() に行く可能性が高く、Android OS が onRestart() を探しているが、それが見つからないためにフリーズ/再起動するということです。

次に、アクティビティを再開するときに 、ゲーム データを保持しながらワーカー スレッドを再開するには、どのようなアクションが必要ですか?

restartという言葉の使い方に注意してください。アプリケーションを一時停止して再開したい (再起動しない)。onPause() でデータを保存します (データベースまたはその他の保存機能を使用します)。onResume() でデータをロードします。ただし、これらのメソッドを埋めるだけであれば、アクティビティは通常どおり再開されるはずです。

ここで、アプリケーションを再起動するときに状態を保存する場合は、onStop() および/または onDestroy() で状態を保存する必要があります。onStart() で状態をロードする必要があります。状態を保存するために、これを確認できます。

https://stackoverflow.com/a/151940/2498729

Eclipse (または他の IDE を使用してアプリケーションを実行/テストする) を使用している場合:

あなたが説明したことから、おそらく AndroidManifest.xmlでandroid:launchModeをオーバーライドしたか、Eclipse から「run as」でテストしている場合は、インストールして自動起動した後にアプリケーションを終了してみてください。次に、エミュレーターから再度開始し、ホーム ボタンの動作をテストします。これは、Android が Eclipse から起動したときにアクティビティを OS スタックに配置せず、ホーム ボタンの動作が通常どおりではないためだと思います。これで問題が解決しない場合は、 http://developer.android.com/guide/topics/fundamentals.html#lmodesを読んでみてください。

StartupActivity に launchMode を設定しました。次に、それを削除しました(「singleTask」に設定されていましたが、希望どおりに動作します。アプリは、期待するアクティビティ、つまり StartupActivity ではなく MainActivity に「再開」されます。

ソース:

https://stackoverflow.com/a/1619461/2498729

http://developer.android.com/guide/topics/manifest/activity-element.html

これによれば:

https://stackoverflow.com/a/3002890/2498729

andoird:launchMode を " Standard " (または " default ") に変更する必要があります。

Standard: A > B > HOME > B  (what you want)
SingleTask: A > B > HOME > A (what you don't want)
于 2013-08-07T19:07:19.613 に答える