質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.37%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Android Studio

Android Studioは、 Google社によって開発された、 Androidのネイティブアプリケーション開発に特化した統合開発ツールです。

Q&A

解決済

2回答

195閲覧

別スレッドの処理終了を受けてメインスレッドの処理を再開させたい

tanuki_

総合スコア39

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Android Studio

Android Studioは、 Google社によって開発された、 Androidのネイティブアプリケーション開発に特化した統合開発ツールです。

0グッド

0クリップ

投稿2024/11/12 02:11

実現したいこと

ボタン押下時に別スレッドにて電文送信を行い、電文送信結果の終了を受けてメインスレッドの処理を再開さっせたい。

発生している問題・分からないこと

https://www.bold.ne.jp/engineer-club/java-threadを参考に組んでみましたが送信結果受信処理が終わる前にメインスレッドの処理が
再開してしまいどう組めば良いのか分からない状態です。

該当のソースコード

java(ボタン押下時の処理)

1 // 登録確認のダイアログ表示 2 private void makeInsertMessage(String message){ 3 // BuilderからAlertDialogを作成 4 new AlertDialog.Builder(this) 5 .setTitle("予約登録の確認") 6 .setMessage(message) 7 .setPositiveButton( 8 "はい", 9 new DialogInterface.OnClickListener() { 10 @Override 11 public void onClick(DialogInterface dialog, int which) { 12 //入力チェック 13 if(inputCheck()) { 14 idInEntryBusinessDay = mGlobalSetting.dbData.getIdInEntryBusinessDay(storeCode, entryBusinessDay); 15 mGlobalSetting.dbData.deleteReservationTemp(storeCode); 16 ReservationData data = setData(); 17 18 // 更新後データに新規登録する予約データを設定する 19 NearbyStore.setUpdateReservationData(data); 20 21 //予約一時データ 22 setInsertTempData(setTempData(data)); 23 //予約一時データ 24 mGlobalSetting.dbData.insertData(ReservationTempData.TABLE_NAME, insertData); 25 26 //電文送信 27 mSendEnd = false; 28 sendTelegramThread sendTelegram = new sendTelegramThread(); 29 sendTelegram.run(TransConstants.REQUEST_INSERT_UPDATE_RESERVE); 30 sendTelegram.start(); 31 //sendTelegram(TransendTelegramsConstants.REQUEST_INSERT_UPDATE_RESERVE); 32 33 try { 34 sendTelegram.join(); 35 } catch (InterruptedException e) { 36 e.printStackTrace(); 37 } 38 //予約データ 39 if(mSendEnd) { 40 setInsertData(data); 41 finish(); 42 } 43 } 44 } 45 }) 46 .setNegativeButton( 47 "いいえ", 48 new DialogInterface.OnClickListener() { 49 @Override 50 public void onClick(DialogInterface dialog, int which) { 51 52 53 54 } 55 }) 56 .show(); 57 } 58

java(電文送信処理)

1 class sendTelegramThread extends Thread { 2 public void run(int requestCode) { 3 sendTelegram(requestCode); 4 } 5 } 6 7 /** 8 * 伝文送信を行う 9 * 10 * @param requestCode 送信伝文の種類 11 */ 12 private void sendTelegram(int requestCode) { 13 14// // プログレスの表示 15// MainActivity.this.getWindow().addFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE); 16// mProgressDialog = new CustomProgressDialog(MainActivity.this); 17// mProgressDialog.getWindow().addFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE); 18// mProgressDialog.show(); 19// 20 switch (requestCode) { 21 case TransConstants.REQUEST_INSERT_UPDATE_RESERVE: 22 // 伝文の送信 23 FileUtils.outputLogFile(getApplicationContext(), Constants.LOG_RESRVE_REGISTRATION, "情報登録上書き伝文 開始", null); 24// new Thread(() -> { 25 //各項目設定 26 mGlobalSetting.sendReserveInData = mSendReserveItem; 27 // 登録/上書き伝文の送信データを取得 28 SendInsertUpdateReserveData insertUpdateReserveData = TelegramDataCreation.createSendInsertUpdateReserveData(mGlobalSetting); 29 // 伝文送信 30 new Connector(this).executeInsertUpdateReserve(getApplicationContext(), insertUpdateReserveData); 31 32// }).start(); 33 break; 34 default: 35 break; 36 } 37 } 38 39 @Override 40 public void onConnectComplete(int requestCode, ReceivedData receivedData) { 41 mReceivedData = receivedData; 42 43 switch (requestCode) { 44 case TransConstants.REQUEST_INSERT_UPDATE_RESERVE: 45 // 情報登録/上書き伝文 46 mInsertUpdateReserveHandler.sendEmptyMessage(0); 47 break; 48 default: 49 break; 50 } 51 52 } 53 /** 54 * 情報取得伝文用ハンドラー(この処理の終了を待ち受けたい) 55 */ 56 @SuppressLint("HandlerLeak") 57 private Handler mInsertUpdateReserveHandler = new Handler() { 58 @Override 59 public void dispatchMessage(Message msg) { 60 super.dispatchMessage(msg); 61// if (mProgressDialog != null && mProgressDialog.isShowing()) { 62// mProgressDialog.dismiss(); 63// } 64// ReserveRegistrationActivity.this.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE); 65 66 // 送信判定 67 if (mReceivedData != null && mReceivedData.isSuccess()) { 68 FileUtils.outputLogFile(getApplicationContext(), Constants.LOG_RESRVE_REGISTRATION, "情報登録上書き伝文 成功", null); 69 Utils.savePosDate(getApplicationContext(), mReceivedData.getPosDate()); 70 mSendEnd = true; 71 } else { 72 FileUtils.outputLogFile(getApplicationContext(), Constants.LOG_RESRVE_REGISTRATION, "情報登録上書き伝文 失敗:" + mReceivedData.getStatus(), null); 73 outputDebugLog("予約情報登録/上書き伝文送信処理失敗 status: " + mReceivedData.getStatus()); 74 75 mSendEnd = false; 76 // エラーダイアログを開く 77 showTelegramError(mReceivedData.getStatus()); 78 } 79 } 80 }; 81 82 /** 83 * 予約情報取得伝文用ハンドラー 84 */ 85 @SuppressLint("HandlerLeak") 86 private Handler mDeleteReserveHandler = new Handler() { 87 @Override 88 public void dispatchMessage(Message msg) { 89 super.dispatchMessage(msg); 90// if (mProgressDialog != null && mProgressDialog.isShowing()) { 91// mProgressDialog.dismiss(); 92// } 93// ReserveRegistrationActivity.this.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE); 94 95 // 送信判定 96 if (mReceivedData != null && mReceivedData.isSuccess()) { 97 FileUtils.outputLogFile(getApplicationContext(), Constants.LOG_RESRVE_REGISTRATION, "情報消去伝文 成功", null); 98 outputDebugLog("情報消去電文送信処理成功"); 99 Utils.savePosDate(getApplicationContext(), mReceivedData.getPosDate()); 100 } else { 101 FileUtils.outputLogFile(getApplicationContext(), Constants.LOG_RESRVE_REGISTRATION, "情報消去伝文 失敗:" + mReceivedData.getStatus(), null); 102 outputDebugLog("情報消去電文送信処理失敗 status: " + mReceivedData.getStatus()); 103 104 // エラーダイアログを開く 105 showTelegramError(mReceivedData.getStatus()); 106 } 107 } 108 }; 109 110 /** 111 * 伝文エラーダイアログを表示する 112 * 113 * @param errorCode 伝文エラーコード 114 */ 115 private void showTelegramError(String errorCode) { 116 alertToShowByTelegramErrorOfReserveInsertUpdate(this, errorCode,ReserveTimetableActivity.class); 117 } 118 119 /** 120 * 伝文の通信エラーダイアログを表示する(登録/上書き) 121 * 122 * @param activity 呼出元の画面 123 * @param errorCode 伝文のエラーコード 124 */ 125 public void alertToShowByTelegramErrorOfReserveInsertUpdate(@NonNull Activity activity, String errorCode, Class returnToClass) { 126 FileUtils.outputLogFile(activity.getApplicationContext(), Constants.LOG_ALERT, "伝文エラー:" + errorCode, null); 127 // Activity画面の操作を無効にする 128 activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE); 129 130 boolean mDialogFrag = true; 131 132 // タイトルとメッセージの生成 133 String title; 134 String message; 135 if (errorCode.equals("B5")) { 136 // 「B5」エラーの場合のみ異なるメッセージを出す 137 title = "登録エラー"; 138 message = "予約時間が重複している為予約を完了する事が出来ませんでした"; 139 140 } else { 141 title = activity.getString(R.string.confirm_telegram_error_title); 142 message = activity.getString(R.string.confirm_telegram_message) + "\nエラーコード:" + errorCode; 143 } 144 145 if (mDialogFrag) { 146 //ダイアログ表示予定 147 } 148 } 149

試したこと・調べたこと

  • teratailやGoogle等で検索した
  • ソースコードを自分なりに変更した
  • 知人に聞いた
  • その他
上記の詳細・結果

現状送信処理が終わるまでは待機出来ていますが、
肝心の受信処理の終了を待つという実装が出来ていません。
join()で待つという事は分かりましたので組み込んでいます。

補足

Android10
java8.1

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

xebme

2024/11/12 16:40

start/joinとスレッドにしなくてもよいと思いますが、受信まで1スレッドとすればjoin不要。受信完了後に自分にイベントを投げて通知する。失敗通知も考慮。
tanuki_

2024/11/13 02:37

アドバイス通り実装した所上手くいきました。 ありがとうございました。
jimbe

2024/11/13 02:46

AndroidStudio は開発ツールです。AndroidStudio 固有の問題でなければ、つまり他の開発ツールを使っても発生する問題であれば、 "AndroidStudio" のタグは付けないほうが良いかと思います。 そして、 Java だけだと環境が分かりませんので(補足へのバージョン表示は残したまま) "Andriod" のタグを付けて頂くと良いと思います。
guest

回答2

0

質問とは関係ありませんが

java

1 SendTelegramThread sendTelegram = new SendTelegramThread(); 2 sendTelegram.run(TransConstants.REQUEST_INSERT_UPDATE_RESERVE); 3 sendTelegram.start(); 4 5 try { 6 sendTelegram.join(); 7 } catch (InterruptedException e) { 8 e.printStackTrace(); 9 } 10 11: 12 13class SendTelegramThread extends Thread { 14 public void run(int requestCode) { 15 sendTelegram(requestCode); 16 } 17}

(クラス名はパスカルケースが常道ですので変更しています)

勘違いされておられるようですが、"Thread クラスのメソッドは全て別スレッドで実行される" 訳ではありません。
SendTelegramThread の run(int) メソッドを直接呼び出した場合(上記の 2 行目)は単に現在のスレッドでそのまま実行されます。
Thread (を継承した) クラスにおいて別スレッドで実行されるのは start() メソッドを呼び出すことで内部から実行される run() メソッドだけですので、上記の 3 行目で SendTelegramThread の run() メソッドが別スレッドで実行され(オーバーライドされていないので)即終了し、 6 行目での join はほぼ意味がありません。

何かパラメータを渡してそれを用いた事を別スレッドで実行したい場合は、コンストラクタでパラメータを渡してフィールドに保存し、 run メソッドではそのフィールド値を用いるようにすることになります。

java

1 SendTelegramThread sendTelegram = new SendTelegramThread(TransConstants.REQUEST_INSERT_UPDATE_RESERVE); 2 sendTelegram.start(); 3 4 try { 5 sendTelegram.join(); 6 } catch (InterruptedException e) { 7 e.printStackTrace(); 8 } 9 10: 11 12class SendTelegramThread extends Thread { 13 private int requestCode 14 SendTelegramThread(int requestCode) { 15 this.requestCode = requestCode; 16 } 17 @Override 18 public void run() { 19 sendTelegram(requestCode); 20 } 21}

投稿2024/11/13 03:57

jimbe

総合スコア13168

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

自己解決

今回はスレッド化する必要なし。
受信後自分にイベントを投げる事で解決

投稿2024/11/13 02:38

tanuki_

総合スコア39

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.37%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問