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

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

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

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

Android

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

Q&A

解決済

2回答

3909閲覧

【android】handlerの中と外で変数の値が変わる

hanhunhun

総合スコア100

Java

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

Android

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

0グッド

0クリップ

投稿2016/07/06 08:26

お世話になっております。

タイトルの件、マルチスレッド処理に対して深い理解力がないため原因究明ができないでおります。

詳しく説明すると

java

1 //xmlparse開始 2 new Thread(new Runnable(){ 3 @Override 4 public void run(){ 5 try{ 6 URL url = new URL("URL" ); 7 Log.d("URL",url.toString()); 8 HttpURLConnection con = (HttpURLConnection)url.openConnection(); 9 String str = InputStreamToString(con.getInputStream()); 10 Log.d("xml",str); 11 XmlPullParser xpp = Xml.newPullParser(); 12 try{ 13 xpp.setInput(new StringReader(str)); 14 }catch (XmlPullParserException e){ 15 Log.d("XmlPullParser", "Error"); 16 } 17 18// XML解析 19 try { 20 int eventType; 21 eventType = xpp.getEventType(); 22 23 while (eventType != xpp.END_DOCUMENT) { 24 if((eventType == xpp.START_TAG)){ 25 if("Prospect_Date".equals(xpp.getName())){ 26 parts1 = xpp.nextText(); 27 }else if("Prospect_Name".equals(xpp.getName())){ 28 parts2 = xpp.nextText(); 29 }else if("Prospect_Number".equals(xpp.getName())){ 30 31 }else if ("countNum".equals(xpp.getName())) { 32 count = Integer.parseInt(xpp.nextText()); 33 handler.post(new Runnable() { 34 @Override 35 public void run() { 36 btn = new Button[count]; 37 txt2 = new String[count]; 38 } 39 }); 40 } 41 }else if(eventType == xpp.END_TAG){ 42 if("listDetail".equals(xpp.getName())){ 43 txt = parts1 + " " + parts2; 44 Log.d("txt1",txt); **←ここは順番通りテキスト1、テキスト2、テキスト3と入ってくる** 45 handler.post(new Runnable() { 46 @Override 47 public void run() { 48 Log.d("txt2",txt);←なぜかここはテキスト3、テキスト3、テキスト3と入ってくる 49 Log.d("intVal",String.valueOf(i)); 50 ll2 = new LinearLayout(List.this); 51 ll2.setOrientation(LinearLayout.HORIZONTAL); 52 53 btn[i] = new Button(List.this); 54 btn[i].setText(txt); 55 LinearLayout.LayoutParams lllp = new LinearLayout.LayoutParams( 56 LinearLayout.LayoutParams.MATCH_PARENT, 57 LinearLayout.LayoutParams.WRAP_CONTENT 58 ); 59 lllp.weight = 1.0f; 60 ll2.addView(btn[i],lllp); 61 Button menu = new Button(List.this); 62 menu.setText("MENU"); 63 ll2.addView(menu); 64 ll1.addView(ll2); 65 btn[i].setOnClickListener(new drawerOpenListener()); 66 i ++; 67 return; 68 } 69 }); 70 i2 ++; 71 } 72 73 } 74 eventType = xpp.next(); 75 } 76 }catch (Exception e){ 77 78 } 79 }catch (Exception ex){ 80 System.out.println(ex); 81 } 82 83 } 84 }).start();

コード中のコメントで申し訳ないですが要はhandler外で変数txtをLogに出力してもちゃんとループで受け取った順に出力してくれるのですがhandler内で変数txtをLogに出力するとループで最後に帰ってくる値(ここでいうところのテキスト3という文字列)がループ回数分出力されます。

試したこととしましてはデバッグで順に追った場合はhandler内外ともに正常に出力できました。

おそらくhandler内の処理が追い付かず変数の値を上書きしているのかと思いますが解決策がわかりません。
(変数を配列にしたりも試しましたが自分の知識ではうまくいきませんでした)

どうかよろしくお願いします。

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

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

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

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

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

guest

回答2

0

txtの宣言箇所が無いですが、たぶんフィールド変数ですよね?
そうすると、処理の流れは下記のようになります。
1-txtをテキスト1に書き換える、ログ出力。
2-handlerに処理1をポストする。
3-txtをテキスト2に書き換える、ログ出力。
4-handlerに処理2をポストする。
5-txtをテキスト3に書き換える、ログ出力。
6-handlerに処理3をポストする。
7-処理1〜3の実行をする。

つまり、7の段階でtxtはテキスト3になっているので全てテキスト3で処理が実行されてしまいます。

投稿2016/07/06 08:38

yona

総合スコア18155

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

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

hanhunhun

2016/07/06 08:50

handlerにポストした処理をその都度実行することはできないですか? 素人のような返しですみません
yona

2016/07/06 09:13

仕組み上無理ですね。 txtをローカル変数にし、final修飾子をつければいいですよ。
hanhunhun

2016/07/06 15:19

ご回答有り難うございます! なんとか解決しました! 今回の件、掘り下げて学習します!
guest

0

ベストアンサー

txtがThreadのさらに外にある理由が良くわかりませんね・・・

txtのスコープ狭めてしまってもいいのなら

Java

1final String txt = parts1 + " " + parts2; 2Log.d("txt1",txt); 3 4handler.post(new Runnable() { 5 @Override 6 public void run() { 7 Log.d("txt2",txt); 8 } 9});

スコープを変えずに無理やり書くなら

Java

1txt = parts1 + " " + parts2; 2Log.d("txt1",txt); 3 4handler.post(new Runnable() { 5 private String mTxt; 6 public Runnable setTxt(String text){ 7 mTxt = text; 8 return this; 9 } 10 11 @Override 12 public void run() { 13 Log.d("txt2",mTxt); 14 } 15 16}.setTxt(txt));

こんな感じですかね?
試してないので、動かなかったらごめんなさい

投稿2016/07/06 09:09

編集2016/07/06 09:16
abs123

総合スコア1280

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

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

hanhunhun

2016/07/06 09:25

スコープに関して知識が浅いばかりに過剰反応するあまりメインスレッドに置いとけばどこでも使えるだろという浅はかな考えでした、、、まだまだ理解不足なところが多いです(*_*) 無事解決しました!ありがとうございます!
abs123

2016/07/06 09:37

今回の問題はスコープではなく、finalを付ける付けないの問題になりますね。 この問題を正しく理解するには、内部クラス、匿名クラスの仕組みを知る必要があります。 気が向いたら「内部クラス ローカル変数」あたりで検索してみてください。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問