このwhile文、ずっと回っているのでしょうか?(iアプリ・Java)

このQ&Aのポイント
  • この記事では、Javaのiアプリで使われるwhile文について問題点を解説します。
  • また、このwhile文がキーイベント待ちの無限ループとなり、常に回り続けることで、ハードウェアの電力を消費する可能性があることも説明します。
  • 適切な処理を行うために必要なキーイベントの取り扱いについても触れます。
回答を見る
  • ベストアンサー

このwhile文、ずっと回っているのでしょうか?(iアプリ・Java)

このwhile文、ずっと回っているのでしょうか?(iアプリ・Java) //trueを入れたwhile文 while(true){  if(keyEvent == Display.KEY_1){   //ボタン「1」をプッシュされた時の処理(内容は文字列出力など、適当に。)  }  //keyEventを初期化。(少なくとも、「1」ではない数字に)  keyEvent = -555; } //キーイベント(※iアプリ)の処理  public void processEvent(int type, int param) {  if (type==Display.KEY_PRESSED_EVENT) keyEvent=param; } このような記述を書籍で見掛けました。 動作としては、問題なく動いているのですが、 これは、キーイベント待ちの無限ループという感じなのでしょうか? ループしている間、常に回っていて、ハードウェアに仕事をさせている(電力消費)ということなのでしょうか?

  • Java
  • 回答数2
  • ありがとう数9

質問者が選んだベストアンサー

  • ベストアンサー
  • salsberry
  • ベストアンサー率69% (495/711)
回答No.2

Thread.sleep()が入っているのであればかなりマシです。 しかしそれでも、キー入力が無視される可能性があることは変わりません。下記の※B~※Cの間に次のキー入力が来た場合はいいですが、※A~※Bの間に入力されたキーの情報は※Bで上書きされて消えてしまいます。 while(true){  if(keyEvent == Display.KEY_1) { ※A   //ボタン「1」をプッシュされた時の処理(内容は文字列出力など、適当に。)  }  //keyEventを初期化。(少なくとも、「1」ではない数字に)  keyEvent = -555; ※B  try {   Thread.sleep(100);  } catch (Exception e) {  }  ※C } >要するに、キーイベントを受け付けるごとに、ある特定の作業を1回行い、 >作業が終わったら、また、キーイベントを受け付ける状態で待機、 >といった内容にしたいわけです。 行いたい作業の内容にもよりますが、processEvent()と走り続けるrun()メソッドに分けずに、processEvent()の中でその「特定の作業」を実行してしまえばいいのでは?

ict-km48tz
質問者

お礼

>processEvent()と走り続けるrun()メソッドに分けずに、processEvent()の中でその「特定の作業」を実行してしまえば ずっと、このことを考えていたのですが、 これをするのと、しないのとで、何が異なるのか、 私の中で整理できなかったため、なかなかお返事することができませんでした。 現在もその状態は続いておりますが、ほったらかしにしておくわけにもいきませんので、 簡単ではありますが、「お礼」を書かせて頂きました。 私はまだJava初心者であるため、run()がどのような動きをするのか、 よく理解できていないようです。 この run() については、 書籍に記載されているサンプルソースの中で使われていたので、 見よう見まねで使っている、といった感じです。 またよろしければ、色々と教えてください。

その他の回答 (1)

  • salsberry
  • ベストアンサー率69% (495/711)
回答No.1

即刻その書籍をゴミ箱にたたき込みたくなるようなコードですね。 - ビジーループで無駄にCPU時間を消費している (他のスレッドの動きが邪魔される、電力も浪費する) - たとえば「1」をプッシュされた場合の処理中に「2」が押されたとして、processEvent()がkeyEventの値をDisplay.KEY_2に書き換えても、while(true)ループの中でkeyEvent = -555;と上書きされて「2」の入力が無視される可能性がある

ict-km48tz
質問者

お礼

回答ありがとうございます。 書籍の内容を多少、はしょっているため、 その私の、はしょり方に問題があったかもしれません。 まず、その点を、お詫びいたします。(汗) ということで、ちょっと補足しますと、 keyEvent = -555; try {  Thread.sleep(100); } catch (Exception e) { } と、実際には、スリープ処理が入れられていました。 おそらく、これがあることで、 ご指摘の「『2』の入力が無視される可能性が」という問題には 対処できているのかな、と思います。 (このスリープ処理にそんな機能があるとは知らず、 はしょってしまった私に問題がありそうです。申し訳ないです。 ※もし、そういう機能があったのだとしたら、の話ですが。) それと、質問文に記載したコードは、 public class MyClass extends Canvas implements Runnable {   private int keyEvent=-555;   //細かい処理(はしょります)  public void run() {   //「ここに納まる」  } } 上記のように、 run()の中に入れられる形となります。 これが、while(true)の無限ループとどう関係があるかは分かりませんが、 質問当初は関係ないと思い、 ただただwhile(true)だけに着目し、その無限ループについて、 質問をさせていただきましたが、 こちらも、はしょってはいけない類だったのでしょうか。 実際、このアプリが悪いのかは分かりませんが、 超異常的なスピードで電池が消耗していました。 この無限ループは、 基本的に、キーイベントを待ち続ける間、ずっとCPUを動かし続けているのでしょうか? こういった処理を、電力消費を抑えた形で行いたい場合、 どういうコードを書くと良さそうでしょうか。 要するに、キーイベントを受け付けるごとに、ある特定の作業を1回行い、 作業が終わったら、また、キーイベントを受け付ける状態で待機、 といった内容にしたいわけです。 もし、宜しければ、また教えて下さい。宜しくお願い致します。

関連するQ&A

  • iアプリ/サイコロの作り方

    Doja5.1 J2SDK1.4.2 を使ってソースを書いています。 まずサイコロを振るプログラムを作って、そのあとサイコロの数字を画像で表示できるようなものを作りたいです。 サイコロの画像はgifで用意してあります。 まずサイコロを振るプログラムですが以下のように書きました。 しかし、エラーが出ないにも関わらずエミュレータで動きません。 どこが間違っているのかどなたか教えてください。 また、画像を表示するほうのプログラムはどこを変えれば良いでしょうか。 よろしくお願い致します。 import com.nttdocomo.ui.*; import java.util.Random; class MainCanvas extends Canvas { int dice[] = new int[8*2]; Random rnd = new Random(); boolean init_flg = false; public MainCanvas() { setSoftLabel(Frame.SOFT_KEY_1,"サイコロ"); setSoftLabel(Frame.SOFT_KEY_2,"終了"); } public void paint( Graphics g ) { if(init_flg == false) { init_flg = true; return; } g.clearRect(0,0,200,2*8*13+30); int i; for(i=0;i<8*2;i++) { g.drawString(Integer.toString(i+1)+"回目のサイコロ",0,i*13+30); g.drawString(Integer.toString(dice[i]),100,i*13+30); } } public void processEvent( int type, int param ) { if( type == Display.KEY_PRESSED_EVENT ) { if( param == Display.KEY_SOFT1 ) { int i; for(i=0;i<8*2;i++) { dice[i] = rnd.nextInt(11)+2; } repaint(); } else if( param == Display.KEY_SOFT2 ) { IApplication.getCurrentApp().terminate(); } }

    • ベストアンサー
    • Java
  • iアプリで連続して判定を行うときの誤動作。

    iアプリで低次元イベント処理?をしてます。 public void processEvent( int type , int param ){  if( imageIndex == SS ){   if( ( type == Display.KEY_PRESSED_EVENT ) && ( param == Display.KEY_SOFT1 ) )    toMenu(); ・・・・ のようにボタンの押し判定をしたいのです。 このプログラムは画像をpaintメソッドの中で書き換える だけのプログラムでボタンの判定によって 画像を書き換えて一種のXMBのように動作させようとしています。 iアプリのメニュー部分の試作なんです。 ただ、連続してボタン判定が行われてしまうので困っています。 今、画像ごとに画像番号があり、その画像番号をif文で判定して 画像切り替えを行うのですが、if文の中で プロセスイベントのでかいくくり{  ・・・  if(ログイン画面){   決定ボタン→ログインしたメニュー画像へ   このとき、ログインフラグ・メニューフラグtrueへ。  }  if(画像番号1){   ソフトキー1なら    → メニューに戻る  }  if(画像番号2){   ソフトキー1なら    → メニュー戻る  }  if(ログインフラグ){   if(ソフトキー1)    投稿画像画面へ   「その他」   ・上下左右が押されたら画像切り替える。   ・決定ボタンが押されたらメニューフラグはfalse  } } 少しわかりにくいですが上のような略で説明しますと ・投稿画面ではソフトキー1でメニューに戻る ・その他のメニューではソフトキー1でメニューに戻る これが問題なのですが ・メニューではソフトキー1で投稿画面にいく。 このようにプログラムをすると 各種メニュー、または投稿画面を表示しているときに ソフトキー1でメニューに戻ろうとすると その結果、メニューでソフトキー1が押されたように判定され その結果再び投稿画面にいく。 以下ずっと続く。 という風になってしまい、投稿画面から出れなくなってしまいます。 このような状況を解決する方法はありますか? わかりにくいところがあればお答えしますので よろしくお願いします。

    • ベストアンサー
    • Java
  • iアプリの作成で画像が再描画されません。

    iアプリの作成で画像が再描画されません。 どうしても解決できないのでご教示下さい。 iアプリの作成をしながら勉強しています。 利用しているプロファイルはdoja 5.1です。 class MainCanvas extends Canvas {  public void paint(Graphics g) {   MediaImage mi = MediaManager.getImage("resource:///6.gif");   try {    mi.use();   } catch(Exception e) {    //何らかの例外処理   }   Image image = mi.getImage();   getGraphics().drawImage(image, 20, 0);  }    public void processEvent(int type, int param) {  if (type==Display.KEY_PRESSED_EVENT) {     if (param == Display.KEY_SELECT) {      Dialog dlg = new Dialog(Dialog.DIALOG_YESNO, "終了");      dlg.setText("終了しますか?");      int result = dlg.show();      if (result == Dialog.BUTTON_YES) {       IApplication.getCurrentApp().terminate();      }     }   if (param == Display.KEY_SOFT1) {    MediaImage mi = MediaManager.getImage("resource:///9.gif");    try {     mi.use();    } catch(Exception e) {     //何らかの例外処理    }    Image image = mi.getImage();    getGraphics().drawImage(image, 0, 0);         }    }  } } こんなクラスがあった時、ダイアログがキャンセルされると、 「9.gif」の方がキャンバス上から消えてしまいます。 どういう作りにすると、キャンバスから画像が消えなくなる のでしょうか?

    • ベストアンサー
    • Java
  • iモードのプログラムについて質問です

    iアプリのプログラム作成中の疑問です。 現在、iアプリで資料をCanvasで作成しています。 初心者ということもあり、必要事項を単純にプログラムしておりましたが、プログラム行数が過大となり、容量(32k)オーバーというエラーが出てしまい、まだまだ盛り込みたいものがあるので何か方法があるのではないか、ということで記入した次第です。 自分なりに考えた方法はあるのですが、実際できるのであればプログラムを教えてください。 HTML等のようにクリック一つで別のプログラムに移動できるようなことは出来るのでしょうか? 例) 親 子1 子2 (キーイベントを利用し、親ファイルから子を呼び出す) if (keyEvent==Display.KEY1) 子1ファイルを呼び出す else if (keyEvent==Display.KEY2) 子2ファイルを呼び出す よろしくお願いいたします。

    • ベストアンサー
    • Java
  • while構文について質問

    以下は、ソースコードの一部です。それを見た上で私の質問に答えてください。 int i=0; while(true) System.out.println(i); i++ 質問:何故、whileの反復条件に「true」を書くと、無限ループになるのですか? その理由は、「while構文は、括弧の中の反復条件の判定の結果がtrueなら、処理を行うので、括弧の中にtrueを書くと、反復条件はtrueのまま変わらないので、その判定結果はtrueと判断されつづけ無限ループする」こういうことでしょうか?

    • ベストアンサー
    • Java
  • while文とif文

    #include <stdio.h> void main() { char str[2][6] = {"hello","lop"}; int i = 0; while(i < 2){ printf("%s\n", str[i++]); } } 上のプログラムの条件判定の部分にif文を つかうとhelloという文字列しか出力されず while文を使うとhelloとlop 二つ出力され ます。上の条件判定のif文にした時ととwhile 文にした時の違いはどこなのでしょうか?? どなたかご教授よろしくお願いしますm(_ _)m

  • Java初心者です。どうか教えてください><

    1週間ほど前からJavaの勉強を始めたものです。初歩的な質問で申し訳ないのですが、是非おしえていただきたくて投稿いたしました。 秀和システムからでている「わかりやすいJava入門編」を使って勉強しているのですが、課題の1つでつまづいてしまい、解決法がわからないので質問させていただきました。 課題の内容は以下です。 1、10本のうち3本が当たりで、最大10回引ける。あたりが出たら取り出す。3つ全てあたりが出たら終了。 2、eclipseのコンソール画面上から「キーをタイプすればくじが引けます」と表示、キーを入力すればくじ引き開始。 3、キー入力後0.1秒ごとに ■ が表示され、1秒後10個になった時点でくじ引き結果表示。 そこで、わたしは、まずint[ ]の配列を10個用意し、ループ分で[0]~[9]まで順にランダムに0~9の数字を入力し、 i番目の[i]に入っている数字が、それより以前の配列に入っている場合、[i]配列の抽選をやりなおす、というやり方でやろうと思って以下のような書き方をしたのですが、どうやら間違っているようで重複の場合のやり直しをしてくれません;; 初心者なので、見づらい書き方をしているかもしれませんがお許しください>< package exercise; import lib.Input; public class Lot_6 { static int[] lot = new int[10]; static int i; public static void main(String args[]){ int a = 0; for(int i=0; i < lot.length ;i++){ if (a < 3){ Input.getString("キーをタイプするくじが引けます"); animation(); do{ lot[i]=(int)(10*Math.random()); } while(isTrue()); if((lot[i] == 0) ^ (lot[i] == 1) ^ (lot[i] == 2)){ System.out.println("あたり"); a++; } else { System.out.println("はずれ"); } } else { break; } } } public static void animation() { for(int m = 0;m < 10;m++){ System.out.print("■ "); delay(100); } } public static void delay(int t) { try { Thread.sleep(t); } catch (InterruptedException e) { e.printStackTrace(); } } public static boolean isTrue(){ boolean is = false; for(int n=0;n <= i-1;n++){ if(lot[i] == lot[n]) is = true; else { continue; } } return is; } } そこで、間違っている箇所を調べるために do{ } while();ループの中にSystem.out.println(isTrue());を加え、if(a < 3) { }の内の最後にSystm.out.println(lot[i]);を加えました。 ちゃんと重複した場合isTrue()にTrueを返しているか、重複した場合やりなおしをしてくれているか、を調べるためです。 そしてコンソール画面の実行結果が以下です。 [キーをタイプするくじが引けます] > ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ false はずれ 6 [キーをタイプするくじが引けます] > ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ false はずれ 3 [キーをタイプするくじが引けます] > ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ false あたり 1 [キーをタイプするくじが引けます] > ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ false はずれ 4 [キーをタイプするくじが引けます] > ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ false あたり 0 [キーをタイプするくじが引けます] > ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ false はずれ 4 [キーをタイプするくじが引けます] > ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ false はずれ 4 [キーをタイプするくじが引けます] > ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ false はずれ 5 [キーをタイプするくじが引けます] > ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ false はずれ 9 [キーをタイプするくじが引けます] > ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ false あたり 2 数字が重複していますし、trueが一個もありません。 ということはisTrue()メソッドの部分で誤りがあるんでしょうか? public static boolean isTrue(){ boolean is = false; for(int n=0;n <= i-1;n++){ if(lot[i] == lot[n]) is = true; else { continue; } } return is; } こう書けば、lot[i]がlot[0]~lot[i-1]の間でいつでも重複しているものがあれば boolean is = true;により上書きされて、isTrue()はtrueが返されると思ったのですがそうはならないのでしょうか。 すいません。いろいろ手は尽くしたのですがどうしても分からなくて質問させていただきました。 ご回答いただけますとうれしいです><b

  • [Java] while(true)の意味

    Javaの参考書で、下記の文がありました。 ... while(true){ 処理 } ... whileの条件式で“true”と書いてありますが、trueではなくなる(falseになる)のは どのような処理が実行された時でしょうか? 出来れば具体的なコードでご教示頂けると助かります。 宜しくお願い致します。

    • ベストアンサー
    • Java
  • while文について教えてください。

     int num[10] = {2,4,6,8,10,12,14,16,18,20}; int n1 ,i;  i=0; n1=10; while(i++<n1) n1-=i; でプログラム実行するとwhile(i++<n1)でn1-=i;のとき  i=0の値は1になり、n1-1=9になると思うのです。  しかし、解説文を読むとn1-i=10のままなのです。  後置インクリメントでi++なので次のn1-i=i;のときは  既にi=1増える形だと思うのですがちがうのですか?  どなたか教えてくれるとたすかります。 

  • DoJaで押しっぱなしのキー処理

    DoJaプログラミング初心者です。 Canvasでメニュー画面を描画して、下キーでメニューを選び、決定キーで処理へ分岐するようにしておりますが、メニューの項目は10個くらいあるので、下の方に移動するには下キーを何回も押さなければなりません。 そこで、下キーを押しっぱなしにして下の方まで移動したいと考えています。 ・・・ private int focused = 0; String[] menu = { "aaa", "bbb", "ccc", ・・・・, "jjj" }; public void paint(Graphics g){  for(int i=0; i<menu.length-1; i++){   if(focused == i) {    //ハイライトで描画   } else {    //普通に描画   }  } } public void processEvent(int type, int param){  if(type == Display.KEY_PRESED_EVENT){   if(param == Display.KEY_DOWN){    focused++;    if(focused > 10) {     focused = 0;    }   }   else if(param == Display.KEY_SELECT) {    shori(focused);   }  } } これをどのように変更すれば、実現できるでしょうか?

    • ベストアンサー
    • Java

専門家に質問してみよう