5

基本的に 250K JNI のラッパーであるアプリを作成しています。JNI (ゲーム エンジン) には、handle_penUp(int x, int y) のような API があります。場合によっては、(Java コードへのコールバックを介して) handle_penUp() 内からユーザーにクエリを実行する必要があるため、クエリの実装に使用するダイアログをブロックする必要があります。

実行のメインスレッドがブロックできないことを理解しています。そのため、ブロックが必要なコールバックが発生する可能性があるすべての JNI 呼び出しを行う 2 番目のスレッドを作成しました。2 番目のスレッド内で、ブロッキング ダイアログを表示する必要がある場合は、セマフォで startActivityForResult() を呼び出してから acquire() を呼び出します。メイン スレッドで onActivityResult() が呼び出されると、同じセマフォで release() が呼び出されます。

これは、クエリが新しいアクティビティとして実装されている場合は機能しますが、既存のアクティビティ内で showDialog() を使用したい場合は機能しません。ログ メッセージは、私のスレッドが Looper を必要としていると教えてくれます。私は1つ追加しています-そしてそれが機能するかどうかについての情報を追加します-しかし、ここで間違った道を進んでいるように感じます. 私が必要としているのは、ブロッキング ダイアログを実行するためのレシピです (他のすべてのプラットフォームにブロック ダイアログがあり、移植されたコードがしばしばそのように機能するという理由だけで役立つ場合)。

4

2 に答える 2

2

これは、タッチ スレッドからビューを表示/非表示に設定する際に発生した問題に非常に近いように思えます。

問題は、別のスレッドから GUI でいくつかの操作を実行できないことです (これはあなたの場合です)。

あなたがする必要があるのは、アクティビティで宣言したメインスレッドでハンドルを使用することです

public static final Handler handlerVisibility = new Handler() {
    public void handleMessage(Message msg) {
        int visibility = msg.getData().getInt("visibility");
        view.setVisibility(visibility);
    }
};

public static のオプションを選択して、どこからでもアクセスできるようにしました (一度に複数の呼び出しを行うことはなく、それをサブクラスに渡すのが面倒だったため)。

次に、このハンドラーにメッセージを送信します。ハンドラーはGUIと同じスレッドにあるため、機能します^^

Message msg = MainActivity.handlerVisibility.obtainMessage();
    Bundle b = new Bundle();
            b.putInt("visibility", View.VISIBLE);
    msg.setData(b);
            MainActivity.handlerVisibility.sendMessage(msg);

これにより、ルーパーエラーが解決され、あるスレッドから別のスレッドに GUI リクエストを送信できるようになります

それが役に立てば幸い

ジェイソン

于 2010-10-27T09:32:20.003 に答える
0

2つのUIスレッドは絶対に必要ありません。制御フローと表示(つまり、描画、アクティビティの開始、ダイアログの表示などに関連するもの)に関しては、AndroidSDKと通信するスレッドは1つだけである必要があります。

また、実際にスレッドを実行し続けたくないことにも注意してください。すべてがイベントに基づいているため、コードが何かに応答し、何かを実行してから、できるだけ早く終了する必要があります。

「ブロック」とはどういう意味ですか?何をブロックする必要がありますか?単にイベントへの応答を停止する必要がある場合は、ダイアログが表示されている間はブール値をtrueに設定し、trueの間はすべてのイベントを無視してみませんか?

于 2010-06-29T21:53:18.960 に答える