わかりました「すべて」を試して、検索したものをすべて読んでみました。質問は非常に単純ですが、何が問題なのか理解できません。
私は NDK (CPP のネイティブ コード) を使用しています。
私は、いくつかの非常に単純なレンダリングが行われた OpenGL GLSurfaceView を持つ非常に単純なアクティビティを持っています。ある時点で、2 つのボタンで単純な AlertDialog を開くことができるようにしたいと考えています。
今、私は多くの異なるアプローチを試しましたが、基本的にすべて「メッセージは、メッセージをポーリングするだけの Java スレッドに投稿され、それを受信すると、実行されるメイン UI スレッドに Handler を持つメッセージを投稿します」という考えに陥ります。 AlertDialog を作成するメッセージ ハンドラー".
次のコードフラグメントのように、GLSurfaceView の onTouchEvent() 関数内の Handler にメッセージを投稿することにより、テスト用に「すべて Java から」実行するなど、他のいくつかのアプローチを試しました。
@Override
public boolean onTouchEvent(MotionEvent e) {
/* code to get the events .. */
if ( maskedAction == MotionEvent.ACTION_DOWN && isUiOn == false)
{
isUiOn = true;
GilesTest2JNIActivity.theHandler.sendEmptyMessage(1);
}
return true;
}
メッセージを受信するハンドラーは次のことを行います。
public class GilesTest2JNIActivity extends Activity {
GilesTest2JNIView mView;
public static AlertDialog mTextInputDialog;
private Context MyContext;
public static Handler theHandler;
public LayoutInflater mInflater = null;
public Handler mHandler;
@Override protected void onCreate(Bundle icicle) {
super.onCreate(icicle);
Log.i ("Giles OnCreate ","creating appl.");
MyContext = this;
mInflater = (LayoutInflater) getSystemService(MyContext.LAYOUT_INFLATER_SERVICE);
mHandler = new Handler(){
public void handleMessage(Message msg){
AlertDialog.Builder builder = new AlertDialog.Builder(MyContext);
Log.i ("handler","builder");
builder.setView(mInflater.inflate(R.layout.dialog_signin, null));
builder.setTitle("User - Login");
builder.setMessage("Please enter your username and pwd");
builder.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
GilesTest2JNILib.nativeSendInputText( "BBB", "AAA");
//dialog.dismiss();
mView.isUiOn = false; // signal this is OFF
}
} );
builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
dialog.cancel();
Log.w ("Keyboard","Kb is going away via CANCEL");
GilesTest2JNILib.nativeSendInputText( "**", "**" );
mView.isUiOn = false; // signal this is OFF
}
});
mTextInputDialog = builder.show();
mTextInputDialog.setCanceledOnTouchOutside(false);
mView.isUiOn = true; // signal this is ON
}
};
/* rest of onCreate() .. */
}
AlertDialog が表示され、すべて正常に動作しているように見えますが、数秒後にすべてがフリーズし、エラー メッセージは表示されず、何も表示されませんが、.step() が呼び出されなくなったため、GLSurfaceView() でのレンダリングも停止します。いかなる種類のエラーメッセージも表示せずにフリーズして停止し、ほぼ永久にそこにとどまり、時折「アプリケーションが応答しません」になります。
この種の動作は Nexus 7 タブレットで発生するようですが、私が持っている別のタブレットでは発生しませんが、4 回目または 5 回目にダイアログを起動/閉じます。
私が理解できた唯一のことは、ある時点であらゆる種類のタッチの受信を停止したように見える、および/または「ウィンドウがない」、および/またはウィンドウが消えたように見える、実際に何が起こっているのか理解できません。
大規模なテストの後に見つけたばかりの情報をいくつか追加しています。
古典的な基本的な OpenGL の例を取得した後、単純に三角形を描画してすべてのコードを元に戻すだけですべてが機能することがわかったので、振り出しに戻って自分のコードで同じことを再試行し、#ifdef を入れ始めました。 「クラッシュポイント」が見つかるまで、さまざまな場所でコードを切り刻みました。
しばらくしてこれを見つけたところ、原因はそのコードにはまったくないように思えますが、バックグラウンドで作業しているオーディオに何か関係があるようです。
これは、OpenSL に基づく非常に単純なプレーヤーであり、サンプルが混在する循環バッファーをループで継続的に再生する 1 つのプレーヤー オブジェクトです。
// at this point we can enqueue the current chunk for playing
theSize = AUDIO_DATA_CHUNK_SIZE*sizeof(SLint16);
#define DO_NOT_ENQUEUE 1
#ifndef DO_NOT_ENQUEUE
result = (*bq)->Enqueue(bq, (void*) curdata, theSize ); /* Size given in bytes. */
#endif
AUDIO_DATA_CHUNK_SIZE は 128 です。これは、サンプルが混在する循環バッファーをループ再生するように設計されており、常に再生されます (サンプルレート 11.025 Khz )。
Alertdialog が起動しているときにサウンドの再生を無効にすると、すべて問題なく動作します。
ある時点でこれが起こっているのを見ることができる以外は、実際に何が起こっているのかわかりません:
12-19 18:56:52.418: W/InputConnectionWrapper.ICC(303): Timed out waiting on IInputContextCallback
12-19 18:56:52.418: I/InputDispatcher(150): Dropped event because it is stale.
12-19 18:56:52.418: I/InputDispatcher(150): Dropped event because it is stale.
12-19 18:56:52.418: I/InputDispatcher(150): Dropped event because it is stale.
何らかの方法でオーディオの再生が入力に干渉しているようです。