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

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

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

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

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

while

Whileは多くの言語で使われるコントロール構造であり、特定の条件が満たされる限り一連の命令を繰り返し実行します。

Android Studio

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

API

APIはApplication Programming Interfaceの略です。APIはプログラムにリクエストされるサービスがどのように動作するかを、デベロッパーが定めたものです。

Q&A

解決済

1回答

1307閲覧

AsynkTask内のwhile文における不具合について(Java, android studio)

a10

総合スコア6

Java

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

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

while

Whileは多くの言語で使われるコントロール構造であり、特定の条件が満たされる限り一連の命令を繰り返し実行します。

Android Studio

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

API

APIはApplication Programming Interfaceの略です。APIはプログラムにリクエストされるサービスがどのように動作するかを、デベロッパーが定めたものです。

0グッド

0クリップ

投稿2020/04/20 07:33

現在、AsynkTask内でAPIをたたき、その結果を取得するというプログラムを書いております。
ただし、APIから受け取った結果が望ましいものではなかった場合(以下の例ではcount項目が0)、
doInBackground内でwhile文を用いることで、望ましい結果が出るまでループさせようという意図のもと、
以下のように実装いたしました。

結果として、count : 0 のような結果が(例として)得られた場合、ループがまわることは確認しました。
しかし、処理が終わらなかったためデバッグしたところ、
ループ中にcount: 200のような結果が得られた場合でも、下記のcountが0のままとなり、while文を抜けられなくなっているようです。

countに新しく値が代入され、while文を抜けるものと思っていたのですが、どうしてこのようになってしまうのでしょうか。

考え方、理由などご存じの方いらっしゃいましたらお教え願います。
(以下では、本質問と関係のないと思われる一部のコードを***で伏せてあります)

Java

1static class MyAsynk extends AsyncTask<String, Void, String> { 2 int count = 0; 3     4    (中略) 5 //ボタンを押した時に非同期処理を開始します 6 @Override 7 protected String doInBackground(String... params) { 8 final StringBuilder result = new StringBuilder(); 9 while (count == 0) { 10 11 Uri.Builder uriBuilder = new Uri.Builder(); //Uri.Builderで要素を入力 12 uriBuilder.scheme("https"); 13 uriBuilder.authority(***); //ホスト 14 uriBuilder.path("***"); 15 uriBuilder.appendQueryParameter("format", "json"). 16 appendQueryParameter("***", ***). 17 appendQueryParameter("page", String.valueOf(***)). 18 appendQueryParameter("applicationId", "***"); 19 20 final String uriStr = uriBuilder.build().toString(); //URIを作成して文字列に 21 Log.d("url", uriStr); 22 try { 23 URL url = new URL(uriStr); //文字列からURLに変換 24 HttpURLConnection con = null; //HTTP接続の設定を入力していく 25 con = (HttpURLConnection) url.openConnection(); 26 con.setRequestMethod("GET"); 27 con.setDoInput(true); //? 28 con.connect(); //HTTP接続 29 30 final InputStream in = con.getInputStream(); //情報を受け取り表示するための形式に 31 final InputStreamReader inReader = new InputStreamReader(in); 32 final BufferedReader bufReader = new BufferedReader(inReader); 33 34 String line = null; 35 while ((line = bufReader.readLine()) != null) { 36 result.append(line); 37 } 38 bufReader.close(); 39 inReader.close(); 40 in.close(); 41 42 JSONObject json = new JSONObject(result.toString()); 43 count = Integer.parseInt(json.optString("count")); 44 45 } catch (Exception e) { //エラーの時に呼び出される 46 Log.e("ERROR", e.toString()); 47 } 48 } 49 return result.toString(); //onPostExecuteへ 50 }

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

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

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

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

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

a10

2020/04/20 11:02

ご回答ありがとうございます。 resultとcountはすでに確認してあり、以下のようになってしまいます。 (例) (1回目のループ) result => count: 0 count => 0 (2回目のループ) result => count: 234 count => 0 ※ほんとは234になってほしい (3回目のループ) result => count: 3 count => 0 ※ほんとは3になってほしい . . . 分かりにくい質問文となってしまい申し訳ございません。
hoshi-takanori

2020/04/20 11:06

謝らなくても大丈夫ですが、result って { や } のついてない count: 234 だけですか?
dodox86

2020/04/20 11:12

ちょっとご説明内容が不確かなので確認ですが、jsonの"count"の値は良いとして、その値を正しくparseIntで取り出せていない、と言うことはありませんか。 JSONObject json = new JSONObject(result.toString()); int count = Integer.parseInt(json.optString("count")); // ここでcountが0になっている、とか
a10

2020/04/20 11:18 編集

すみません、上記の例は簡単のためのもので、実際はjsonの形式で、 { "count": 45, ... }のようになっています。 また、1回目のループの際に、resultのcountが0ではない(1回でループを抜ける)場合、 countには0ではない値がはいっていることを確認できているため、resultからcountは取れているのだと思っています。 (例: Logcatで確認) (1回目のループ) result => count: 235 count => 235 (終)
hoshi-takanori

2020/04/20 11:29

result がループの外で生成されているからでは。
hoshi-takanori

2020/04/20 11:36

result がループの外で生成されて、その後クリアされずに append されてるので、 初回: {"count": 0, ...} 2回目: {"count": 0, ...}{"count": 234, ...} 3回目: {"count": 0, ...}{"count": 234, ...}{"count": 3, ...} とどんどん追加されて、new JSONObject は最初の {"count": 0, ...} の後ろに余計なものがあっても無視するから、では。
a10

2020/04/20 11:49

ご回答ありがとうございます。 その通りでした・・・。resultの内容をきちんと確認していなかったことも原因でした。 お手数をおかけして申し訳ありません、ありがとうございました。
guest

回答1

0

自己解決

追記部分で解決しました。

whileの外で
final StringBuilder result = new StringBuilder();
としていたためでした。

setLength(0)などとしてリセットすることで解決しました。

投稿2020/04/25 17:04

a10

総合スコア6

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問