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

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

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

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

Android

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

Q&A

解決済

4回答

2392閲覧

for文、ループについて

daichanman123

総合スコア32

Java

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

Android

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

0グッド

0クリップ

投稿2016/04/05 07:22

編集2016/04/05 07:35

先ほどの質問と似ていますがよろしくお願いします。

コード public class MainActivity extends Activity implements Runnable{ private Handler mHandler; private FrameLayout frameLayout; TextView tv; int x = 0; @Override protected void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); frameLayout = new FrameLayout(this); setContentView(frameLayout); tv = new TextView(this); frameLayout.addView(tv); mHandler = new Handler(); mHandler.postDelayed(this, 1000); } @Override public void run(){ tv.setText("b"); mHandler.post(new Runnable() { @Override public void run() { try{ Thread.sleep(1000); } catch(InterruptedException e){ } x++; tv.setText("x は" + x); } }); mHandler.postDelayed(this, 2000); } }

上のプログラムを実行すると
b
1秒後
xは1
1秒後
b
1秒後
xは2
が繰り返されます。

runメソッドだけ変更

コード public void run(){ tv.setText("b"); mHandler.post(new Runnable() { @Override public void run() { try{ Thread.sleep(1000); } catch(InterruptedException e){ } x++; tv.setText("x は" + x); mHandler.postDelayed(this, 2000); } }); }

このプログラムの場合実行すると
b
1秒後
xは1
3秒後
xは2
3秒後
xは3
が繰り返されます。

またrunメソッドだけ変更

コード public void run(){ tv.setText("b"); mHandler.post(new Runnable() { @Override public void run() { for(int i = 0; i < 5; i++){ try{ Thread.sleep(1000); } catch(InterruptedException e){ } x++; tv.setText("x は" + x); } } }); }

このプログラムを実行すると
b
5秒後
xは5
と表示されました。

b
1秒後
xは1
1秒後
xは2
と「xは5」まで表示されると思ったのですが、b→5秒後→xは5と表示されたのはどうしてなのでしょうか?
ここではfor文が使えない仕様になっているのでしょうか?

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

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

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

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

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

guest

回答4

0

こんにちは。

for(int i = 0; i > 5; i++){

run()の中のfor文の赤い条件の部分が
iが5より大きい
となっているからではないでしょうか?

for(int i = 0; i < 5; i++){
なら0~4までの間ループされます。

投稿2016/04/05 07:26

編集2016/04/05 07:30
kaputaros

総合スコア1844

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

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

daichanman123

2016/04/05 07:32

回答ありがとうございます。 そうですね笑 間違って書いてしまいました! 質問内容変更しておきます!
guest

0

いっそのことThread.sleep()封印しましょう
UIスレッドに対するThread.sleep()は諸悪の根源です
Thread.sleep()を使用しない実装を考えてみてください。

あとログ入れると、どうなってるかわかるとおもいます。

public void run() {

for(int i = 0; i < 5; i++){ try{ Thread.sleep(1000); } catch(InterruptedException e){ } x++; tv.setText("x は" + x); Log.d("debugTAG", "x は" + x); }

}

見たいな感じで

具体的には、ログはちゃんと出力されているけど、画面上は変わってないことが分かると思います。

投稿2016/04/05 08:31

abs123

総合スコア1280

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

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

daichanman123

2016/04/05 23:58

回答ありがとうございます。 別スレッドを作り、その中でThread.sleep()の処理をするのも避けた方がいいのでしょうか?
abs123

2016/04/06 01:24

自分でスレッドを作成し、管理しているのであれば、使用しても問題ないと思います。 とりあえず、UIスレッドでは自分以外が実装した処理が確実に動くことになるので UIスレッドをsleepするのは避けたほうが良いです。
daichanman123

2016/04/06 01:45

回答ありがとうございます! そうなんですね! 質問文のプログラムのThread.sleep()は別スレッドではなくUIスレッドで使用されていることになるんですか? 一応私なりには別スレッドで作ったつもりなのですが笑
abs123

2016/04/06 02:17

ActictyのonCreate()はUIスレッドから呼ばれます。 そのonCreate()の中でnew Handler()するとUIスレッドに対するHandlerが生成されます。 このHandlerでpost() or postDelayed()すると、UIスレッドで処理が実行されます。 この流れは大丈夫でしょうか?
daichanman123

2016/04/06 02:26

はい! 大丈夫です。 onCreate()以外の場所でnew Handler()をしないといけないということでしょうか?
abs123

2016/04/06 07:50

Handlerに関しては、また別に質問を上げてもらったほうがいいかもしれませんね・・・
daichanman123

2016/04/06 09:03

了解です。 もう少し勉強したいと思います!
guest

0

ベストアンサー

実際にためしてみました。

まず、HandlerとThreadは違うものです。
で、RunnableはHandlerに積む(postする)ことができる部品みたいなものと思って下さい。

forループ等の処理をUIスレッド以外で実行する場合、たとえば以下のようにThreadをnewしてください。

Java

1 @Override 2 public void run(){ 3 new Thread(new Runnable() { 4 @Override 5 public void run() { 6 for(int i = 0; i < 5; i++){ 7 try{ 8 Thread.sleep(1000); 9 } 10 catch(InterruptedException e){ 11 } 12 x++; 13 tv.setText("x は" + x); 14 } 15 } 16 }).start(); 17 }

ただ、実行していただくとわかりますが、このrunは例外(CalledFromWrongThreadException)で落ちます。
原因はUIスレッド以外で画面の更新を行おうとしているからです。

そのため、UIスレッド以外での画面更新は例えば「RunnableをHandlerにpostする」といった具合に実装します。
いろいろ方法はあるとおもいますが、とりあえずご希望に沿うようにするとしたら、このようになります。

Java

1 @Override 2 public void run(){ 3 new Thread(new Runnable() { 4 @Override 5 public void run() { 6 for(int i = 0; i < 5; i++) { 7 try { 8 Thread.sleep(1000); 9 } catch (InterruptedException e) { 10 } 11 x++; 12 mHandler.post(new Runnable() { 13 @Override 14 public void run() { 15 tv.setText("x は"+x); 16 } 17 }); 18 } 19 } 20 }).start(); 21 }

書いたのは私ですがこのソースは非常に汚いです。
「android Handler Thread 違い」等で検索していただくと、より参考になる情報があるかもしれません。

投稿2016/04/06 04:49

tnd-.-b

総合スコア247

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

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

daichanman123

2016/04/06 09:02

回答ありがとうございます^^ とてもわかりやすい解説で理解できました! 本当にありがとうございました。
guest

0

Activity側に制御が返らず、TextViewが更新されないから。のようなきがします。
http://stackoverflow.com/questions/4425660/how-to-refresh-a-textview-while-looping-in-android

投稿2016/04/05 08:03

編集2016/04/05 08:05
tnd-.-b

総合スコア247

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問