2011-12-23 4 views
0

こんにちは、ランダムな情報で毎秒GUIを更新するためにハンドラを使用しようとしています - 情報はタイマーだけではありません。私はいくつかのハンドラを作成しており、2番目のハンドラはその仕事に使うと仮定しています。ハンドラをタイマーとして機能させる

ここで私が間違っていると私を訂正してください: 各ハンドラは1つのスレッドに関連付けられています。つまり、ハンドラが作成されたスレッドです。したがって、onCreate()メソッドでハンドラを作成すると、GUIスレッドにアタッチされます。メインスレッド したがって、タスク/メッセージ/メソッドを特定の時間に実行させるには、handler.postDelayed()メソッドを使用する必要があります。以下は、私のコードの抜粋です:

// Button to use handler - commence when pressed 
    handler2Btn = (Button)findViewById(R.id.handler2_Btn); 
    handler2Btn.setOnClickListener(new View.OnClickListener() 
    { 

     @Override 
     public void onClick(View v) 
     { 
      new Thread() 
      { 
       @Override 
       public void run() 
       { 
        // Create a new thread which will get the message from handler 1 and send it 
        // when the button has been clicked 
        Message msg2 = handler2.obtainMessage(1,"New Message for Handler 2"); 
        handler2.sendMessage(msg2); 

        // Remove any callbacks (messages pending) 
        handler2.removeCallbacks(this); 
        handler2.postDelayed(updateGUI(), 1000); 

       } // End Run 

      }.start();// Start the Thread 

     }// End on Click 
    }); 

そして、GUIを更新し、タイマーなどのTextViewに割り当てられた行為を確実に行動すると仮定されてupdateGUI()メソッド:

private Runnable updateGUI() 
{ 
    return new Runnable() 
    { 

     // Do this every second 
     @Override 
     public void run() 
     { 
      handlerLabelTxt2.append(""+j); 
      j++; 
     } 

    }; 
} 

しかし、どのようなイム取得ボタンを押すと、GUIは更新されますが、毎秒更新されません。ボタンを使用してプロセスを開始するが、そのプロセスをタイマーのように動作させ続けることが意図されている。

postDelayed()メソッドをonCreate()メソッドの本体に移動する必要がありますか?ハンドラが私を混乱させているので、私はここで少し助けが必要です!

おかげ

+0

あなたはhandler2.postDelayed(updateGUI()、1000)を追加したことがあります。 updateGUI()関数内のrun()メソッドの最後まで? –

+0

私はすぐにそれを試してみませんでした – Katana24

+0

それを試しても動作しません。 – Katana24

答えて

0

Ok - ソート済みです。特定のタスクを実行するために、ハンドラと実行可能ファイルの組み合わせを使用しました。私はそれを行うには2つの方法のうちの1つを使用しました。

public class timerTask extends Activity implements Runnable 
{ 
private Handler handler; 

// TextView for the counter 
private TextView counter; 

// Button for the stopping the counter 
private Button stop; 

// Counter 
private int i = 0; 

@Override 
protected void onCreate(Bundle savedInstanceState) 
{ 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.timertask); 

    // TextView to be updated 
    counter = (TextView) findViewById(R.id.counter); 

    // Attach the handler here 
    handler = new Handler(); 
    handler.postDelayed(this, 1000); 

    // Button to stop the runnable - Work in progress, please ignore 
    stop = (Button) findViewById(R.id.stop); 
    stop.setOnClickListener(new View.OnClickListener() 
    { 
     @Override 
     public void onClick(View v) 
     { 
      handler.removeCallbacksAndMessages(timerTask.class); 

     } 
    }); 
} 

@Override 
public void run() 
{ 
    counter.setText(" "+i); 
    handler.postDelayed(this, 1000); 
    i++; 
} 

} 

handler.postDelayed()スケジュール実行する最初のメッセージ/タスク/事:最初は、実行可能な実装することです。私の場合、5秒後にrunメソッドを呼び出すように指示しています。いったん呼び出されると、runメソッドは1秒ごとに実行されます - 1000パラメータでシンボル化されます。

第二の方法は、私はのonCreate()メソッドで実行可能なオブジェクトを作成し、基本的に代わりのRunnableを実装する以外は、第1と同じである。

Runnable r = new Runnable() 
    { 
     public void run() 
     { 
      counter.setText(" "+i); 
      handler.postDelayed(this, 1000); 
      i++; 
     } 
    }; 
    handler.postDelayed(r, 1000); 

私はこのことができます期待。

P.S.どのようにこれを改善することができるだろうか? ありがとう

0

これはTimer実装のための候補者のように見えます。

+0

タイマーはこれには不適切でしょうか?理由は、Android Appとjava.utilライブラリをこのようなタスクに使うべきではないからです。私はここでそれを読む - [リンク](http://developer.android.com/resources/articles/timed-ui-updates.html)] – Katana24

0

あなたのスレッドはhandler2.postDelayed()呼び出し後に即座に終了します。そのため、タイマーとして機能しません。スレッド内にループを作成する必要があります。

+0

あなたは何をお勧めしますか?無限ループに陥ることなく、別のボタンで止めるように言われるまで、何かを続けたい。それについてどうやって行きますか? – Katana24

0

あなたが反対でない場合、私はそれのための私のクロッククラスを提案することができます。ところで、可能な改善

import java.text.SimpleDateFormat; 
import java.util.ArrayList; 
import java.util.Date; 
import android.os.Handler; 
import android.widget.TextView; 
/** 
* The class for creating and refreshing many different fields on different layouts, 
* that can hold actual time and/or date in different formats 
* The formats should be as in http://developer.android.com/reference/java/text/SimpleDateFormat.html. 
* Only present and visible fields are being actualized, so there is no need to clean the clock list after closing an activity 
* 
* Examples of use: 
* 
*  Clock.registerClock((TextView) findViewById(R.id.TimeField), "HH:mm"); 
*  Clock.registerClock((TextView) findViewById(R.id.DateField), "d.M.yyyy EEE"); 
*  Clock.start(10000L); 
* 
* @author Petr Gangnus 
*/ 
public final class Clock { 
    /** 
    * the handler that works instead of timer and supports UI 
    */ 
    static private Handler handler = new Handler(); 
    /** 
    * the interval of the time refreshing 
    */ 
    static private long refreshStep; 

    /** 
    * pairs TextView timer+time/date format 
    */ 
    private TextView clockFace; 
    private String format; 
    private Clock(TextView clockFace, String format){ 
     this.clockFace=clockFace; 
     this.format=format; 
    } 
    // here is the list of views containing the visual timers that should be held actual 
    static private ArrayList<Clock> clocks=new ArrayList<Clock>(); 
    /** 
    * fills all timer fields by actual time value, according to their formats. 
    */ 
    static private Runnable mUpdateTimeTask = new Runnable() { 
     public void run() { 
      for(Clock clock:clocks){ 
       showActualTimeDate(clock); 
      } 
      handler.postDelayed(this,refreshStep); 
     } 
    }; 

    //============================================ public members ==================================================================== 
    /** 
    * add a clock to the list of updating clocks 
    * @param clockFace - the place where the time or date will be shown 
    * @param format - the format of the time/date 
    * @return 
    */ 
    public static boolean registerClock(TextView clockFace, String format){ 
     if (clockFace==null) return false; 
     if(clocks.contains(clockFace)){ 
      // old clockFace 
      clocks.get(clocks.indexOf(clockFace)).format=format; 
     } else { 
      // new clockFace 
      clocks.add(new Clock(clockFace, format)); 
     } 
     return true; 
    } 
    /** 
    * remove a clock from the updating list 
    * @param clockFace 
    * @return 
    */ 
    public static boolean unRegisterClock(TextView clockFace){ 
     if (clockFace==null) return false; 
     if(clocks.contains(clockFace)){ 
      // found clockFace 
      clocks.remove(clocks.indexOf(clockFace)); 
     } else { 
      // not found clockFace 
      return false; 
     } 
     return true; 
    } 
    /** 
    * put in the "place" the actual date/time in the appropriate "format" 
    * @param place 
    * @param format 
    */ 
    public static void showActualTimeDate(Clock clock){ 
     if (clock.clockFace==null) return; 
     if (clock.clockFace.getVisibility()!=TextView.VISIBLE) return; 
     Date thisDate=new Date(); 
     SimpleDateFormat df=new SimpleDateFormat(clock.format); 
     clock.clockFace.setText(df.format(thisDate)); 
    } 
    /** 
    * start the ticking for all clocks 
    * @param step the tick interval 
    */ 
    public static void start(long step) { 
     refreshStep=step; 
     handler.removeCallbacks(mUpdateTimeTask); 
     handler.postDelayed(mUpdateTimeTask, 0); 
    } 
    /** 
    * Stopping ticking all clocks (not removing them) 
    * the calling could be put somewhere in onStop 
    */ 
    public static void stop() { 
     handler.removeCallbacks(mUpdateTimeTask); 
    } 
} 
0
  1. のため、事前に感謝あなたはハンドラからpostDelayed()を使用するようにしてくださいハンドラインスタンスと指定した時間 に呼び出される設定遅れコールバックを作成します。 Runnableでrun()メソッドを指し、その中でコードを実行します。

    Handler mHandler = new Handler(); 
    mHandler.removeCallbacks(mEndPressedState); 
    mHandler.postDelayed(mEndPressedState, 400); 
    
  2. その後、あなたはまた、PostAtTime()を使用することができます)(ハンドラタイマーが実行中

    private final Runnable mEndPressedState = new Runnable() { 
        @Override 
        public void run() { 
         ((ImageButton)btn).setImageDrawable(getResources().getDrawable(R.drawable.icon_normal)); 
        } 
    }; 
    

を通過した後にトリガされることのRunnableを定義します。これにより、定期的なrun()メソッドが呼び出されます。 updateGUI()はrun()で呼び出す必要があります。ここで続きを読む:

Timer implementation on Android (my blog)

関連する問題