web-dev-qa-db-ja.com

Android-コードの一部を5秒ごとにループします

STARTボタンを押すと5秒ごとに2行のコードの繰り返しを開始し、STOPボタンを押すと終了します。 TimerTaskとHandlesを試してみましたが、その方法を理解できませんでした。

public class MainActivity extends Activity {




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


           //final int i;
           final TextView textView = (TextView) findViewById(R.id.textView);
           final Button START_STOP = (Button) findViewById(R.id.START_STOP);
           final ImageView random_note = (ImageView) findViewById(R.id.random_note);
           final int min = 0;
           final int max = 2;
           final Integer[] image = { R.drawable.a0, R.drawable.a1,R.drawable.a2 };



        START_STOP.setTag(1);
        START_STOP.setText("START");


        START_STOP.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
            int status = (Integer) v.getTag();
            if (status ==1) {
                textView.setText("Hello");
                START_STOP.setText("STOP");
                v.setTag(0);

                final Random random = new Random();

                                //************************************************************
                // I would like to loop next 2 lines of code every 5 seconds.//

                                int i = random.nextInt(2 - 0 + 1) + 0;
                random_note.setImageResource(image[i]);

                //************************************************************
                    }

            else
            {
                textView.setText("Bye");
                START_STOP.setText("Let's PLAY!");
                v.setTag(1);
            }


            }
        });     

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }


}
8
Damijan

CountDownTimerを他の回答の1つとして使用することは、これを行う1つの方法です。もう1つは、ハンドラと postDelayed メソッドを使用することです。

private boolean started = false;
private Handler handler = new Handler();

private Runnable runnable = new Runnable() {        
    @Override
    public void run() {
        final Random random = new Random();
        int i = random.nextInt(2 - 0 + 1) + 0;
        random_note.setImageResource(image[i]);
        if(started) {
            start();
        }
    }
};

public void stop() {
    started = false;
    handler.removeCallbacks(runnable);
}

public void start() {
    started = true;
    handler.postDelayed(runnable, 2000);        
}

次に、TimerとTimerTaskを使用した例を示します。

private Timer timer;
private TimerTask timerTask = new TimerTask() {

    @Override
    public void run() {
        final Random random = new Random();
        int i = random.nextInt(2 - 0 + 1) + 0;
        random_note.setImageResource(image[i]);
    }
};

public void start() {
    if(timer != null) {
        return;
    }
    timer = new Timer();
    timer.scheduleAtFixedRate(timerTask, 0, 2000);
}

public void stop() {
    timer.cancel();
    timer = null;
}
26
britzl

次の方法としてCountDownTimerを使用できます。

_private CountDownTimer timer;

timer = new CountDownTimer(5000, 20) {

    @Override
    public void onTick(long millisUntilFinished) {

    }

    @Override
    public void onFinish() {
        try{
            yourMethod();
        }catch(Exception e){
            Log.e("Error", "Error: " + e.toString());
        }
    }
}.start();
_

そして、もう一度タイマーを呼び出すには:

_public void yourMethod(){
    //do what you want
    timer.start();
}
_

タイマーをキャンセルするには、timer.cancel();を呼び出します。

それが役に立てば幸い!

13
Giacomoni

RxJava2/RxAndroid2を使用して、毎秒(または何でも好きなように)メッセージを送信するObservableを作成できます(例:擬似コード)。

Disposable timer = Observable.interval(1000L, TimeUnit.MILLISECONDS)
            .timeInterval()
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Consumer<Timed<Long>>() {
                @Override
                public void accept(@NonNull Timed<Long> longTimed) throws Exception {               
                    //your code here.
                    Log.d(TAG, new DateTime());
                }
            });

停止したいときは、次のように呼び出すだけです。

timer.dispose();

このコードは他のオプションよりもはるかに読みやすくなっています。

7
db80

Handler、CountDownTimer、および通常のTimerの使用の違いに言及する以外に、追加することはあまりありません。 britzlが述べたように、CountDownTimerは内部的にハンドラーを使用するため、ハンドラーを直接使用することと同じです。ハンドラーは、非常に短い期間、Uiのものを実行するために使用されます。例としては、テキストビューのsetTextがあります。計算集中型のタスクの場合、ハンドラーが遅延を引き起こす可能性があります。タイマーは短いタスクのみを実行することもできますが、必ずしもUIに関するものだけではありません。より複雑なタスクでは、新しいスレッドを使用する必要があります。

0
Walter Morawa