0

私はアンドロイドアプリを実装しています。クライアントからサーバーにデータを送信するときに、データが正常に送信されたことをクライアントに知らせたいという問題はありません。AlertDialog を実装しましたが、データを送信すると、「Looper.prepare() を呼び出していないスレッド内でハンドラーを作成できません」というメッセージが表示されます。以下にコードを添付しました。

    private void saveOrder(final Order order) {
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
            try {
                getConnection().saveOrder(order);
                handleSuccessSaveOrder();
            }
            catch (Exception exc) {
                Log.d("--- ERROR ---", exc.getMessage());
                handleException(exc.getMessage());
            }
        }
    });
    thread.start();
}

private void handleSuccessSaveOrder() {
    showAlert(Farsi.Convert(" j "),R.drawable.warning);
    //showActivity(MainMenuActivity.class);
}

private void showAlert(String message, int iconId) {
    alert = new AlertDialog.Builder(ReviewOrderActivity.this);
    alert.setTitle("Status Dialog");
    alert.setMessage(message);
    alert.setIcon(iconId);

      alert.setPositiveButton("OK", new DialogInterface.OnClickListener() {
      public void onClick(DialogInterface arg0, int arg1) {
      showActivity(MainMenuActivity.class); } });


    alert.show();

}
4

4 に答える 4

4

You cannot modify the ui from a non ui thread, use runOnUiThread:

private void saveOrder(final Order order) {
    Thread thread = new Thread(new Runnable() {
        @Override
        public void run() {
        try {
            getConnection().saveOrder(order);
            runOnUiThread(new Runnable() {
                 public void run() {
                   handleSuccessSaveOrder();
                 }
            });

        }
        catch (Exception exc) {
            Log.d("--- ERROR ---", exc.getMessage());
            handleException(exc.getMessage());
        }
    }
});
thread.start();
}
于 2012-12-12T07:37:50.947 に答える
3

UI背景スレッドから変更することはできません。このように使う

private void handleSuccessSaveOrder() {
ReviewOrderActivity.this.runOnUiThread(new Runnable() {

            @Override
            public void run() {
                showAlert(Farsi.Convert(" j "),R.drawable.warning);

            }
        });

    //showActivity(MainMenuActivity.class);
}
于 2012-12-12T07:37:07.663 に答える
2

AlertDialog を表示するハンドラを作成し、上記のコードの代わりに以下のコードを試すと、問題が解決します。

private void saveOrder(final Order order) {
    Thread thread = new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                getConnection().saveOrder(order);
                mHandler.sendEmptyMessage(0);
            }
            catch (Exception exc) {
                Log.d("--- ERROR ---", exc.getMessage());
                handleException(exc.getMessage());
            }
        }
    });
    thread.start();
}

public Handler mHandler = new Handler() {
    @Override
    public void handleMessage(Message msg) {
        handleSuccessSaveOrder();
    }
};

private void handleSuccessSaveOrder() {
    showAlert(Farsi.Convert(" j "),R.drawable.warning);
}

private void showAlert(String message, int iconId) {
    alert = new AlertDialog.Builder(ReviewOrderActivity.this);
    alert.setTitle("Status Dialog");
    alert.setMessage(message);
    alert.setIcon(iconId);

    alert.setPositiveButton("OK", new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface arg0, int arg1) {
            showActivity(MainMenuActivity.class); 
        } 
    });

    alert.show();

}
于 2012-12-12T07:41:40.400 に答える
1

「Looper.prepare() を呼び出していないスレッド内でハンドラーを作成できません」の原因は次のとおりです。

Alert dialogバックグラウンド スレッドでプロセスを実行している間は、UI スレッドを表示できません。

したがって、以下のように UI スレッドにアラート ダイアログを配置しhandleSuccessSaveOrder()ます。

this.runOnUiThread(new Runnable() {
                    public void run() {
                        showAlert(Farsi.Convert(" j "),R.drawable.warning);
                    }
                });
于 2012-12-12T07:41:24.537 に答える