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

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

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

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

Android

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

Q&A

解決済

1回答

2489閲覧

android studioで scheduleAtFixedRateを規定の回数だけ実行する方法に関して

tonyaaa

総合スコア1

Java

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

Android

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

0グッド

0クリップ

投稿2021/10/17 12:00

編集2021/10/17 12:39

前提・実現したいこと

android studio(java)のTimerの使い方について質問です。
現在、2つのtextviewを一定時間ごとに交互に表示させるものを制作しています。
scheduleAtFixedRateを使用して、無限ループさせるところまではできたのですが
例えば1ループを5回繰り返したら一旦別の処理をさせたいと考えています。
text1を1.5秒表示→text2を4.5秒表示(これで1ループでまたtext1から~)
このループを5回繰り返したら、10秒待機してまた元のループに戻したいです。

###試したこと

setOnClickListenerの該当部に for(int i=0; i<=5; i++)
を入れてみました。
scheduleAtFixedRateの処理にfor文がかかっていないのだと思っているのですが
どのようにscheduleAtFixedRateにiを組み込めばいいのか分かりません。
試しにSystem.out.println(i)を入れて確認したのですがfor文は動いているようでした。

for文でうまく回せれば、5回ループ処理を行ったあとに
sleep等で10秒待機させて戻れば、実行したい処理が実現できると考えているのですが
ご教示いただけないでしょうか。
よろしくお願い致します。

該当のソースコード

lang

1 2 start.setOnClickListener(new View.OnClickListener() { 3 @Override 4 public void onClick(View view) { 5 for(int i=0; i<=5; i++) { 6 if (timer == null) { 7 upview.setText("UP"); 8 timer = new Timer(); 9 timer.scheduleAtFixedRate(new MyTimer(), 1500, 6000); 10 downview.setText(""); 11 timer2 = new Timer(); 12 timer2.scheduleAtFixedRate(new MyTimer2(), 6000, 6000); 13 } 14 System.out.println(i); 15 } 16 } 17 }); 18 19 reset.setOnClickListener(new View.OnClickListener() { 20 @Override 21 public void onClick(View view) { 22 if(timer != null){ 23 timer.cancel(); 24 timer2.cancel(); 25 timer.purge(); 26 timer2.purge(); 27 timer = null; 28 timer2 = null; 29 upview.setText(""); 30 downview.setText(""); 31 } 32 } 33 }); 34 } 35 36 private class MyTimer extends TimerTask { 37 @Override 38 public void run() { 39 handle.post(new Runnable() { 40 @Override 41 public void run() { 42 try{ 43 upview.setText(""); 44 downview.setText("STOP"); 45 }catch (Exception ex){ 46 ex.printStackTrace(); 47 } 48 } 49 }); 50 } 51 } 52 53 private class MyTimer2 extends TimerTask { 54 @Override 55 public void run() { 56 handle.post(new Runnable() { 57 @Override 58 public void run() { 59 try{ 60 upview.setText("GO"); 61 downview.setText(""); 62 }catch (Exception ex){ 63 ex.printStackTrace(); 64 } 65 66 } 67 }); 68 } 69 } 70

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

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

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

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

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

jimbe

2021/10/17 12:13

コードは、マークダウンという記法を使ってご提示ください。 マークダウンに関しましてはヘルプを御覧ください。
tonyaaa

2021/10/17 12:39

すみません。マークダウン記法で修正しました。 以後気をつけたいと思います。 ご指摘頂きありがとうございます。
guest

回答1

0

ベストアンサー

scheduleAtFixedRate は、呼び出した瞬間から、指定した処理の一定周期での実行をスケジューリングします。
ですので scheduleAtFixedRate の呼び出しを何度 for で繰り返したところで、処理の回数を数えられるわけではありません。
一定回数で止めたりするのであれば、指定した処理内で呼び出し(呼び出され)回数をカウントし、スケジューリングを止める等をする必要があります。


以下は、Timer.scheduleAtFixedRate では無く Handler.postDelay によって処理するようにしたものです。
FlushTexts クラスが Handler.postDelay によって void run() を実行する度に count を +1 し、その値に応じて各テキストの表示および次の実行の設定を行っています。

MainActivity.java

java

1package com.teratail.q364882; 2 3import androidx.appcompat.app.AppCompatActivity; 4 5import android.os.*; 6import android.util.Log; 7import android.widget.*; 8 9public class MainActivity extends AppCompatActivity { 10 11 private class FlushTexts implements Runnable { 12 private final Handler handler; 13 private final TextView text1, text2; 14 private boolean isRun = false; 15 private int count = 0; 16 17 FlushTexts(Handler handler, TextView text1, TextView text2) { 18 this.handler = handler; 19 this.text1 = text1; 20 this.text2 = text2; 21 } 22 void start() { 23 if(isRun) throw new IllegalStateException("既に実行中です"); 24 count = 0; 25 isRun = true; 26 postNext(0); 27 } 28 void stop() { 29 if(!isRun) return; 30 synchronized(this) { 31 isRun = false; 32 handler.removeCallbacks(this); 33 } 34 } 35 @Override 36 public void run() { 37 if(++count > 10) { //11 38 count = 0; //次は Go に行く 39 setClearState(); 40 } else if(count % 2 == 0) { //2,4,6,8,10 41 setStopState(); 42 } else { //1,3,5,7,9 43 setGoState(); 44 } 45 } 46 private void setGoState() { 47 Log.d("FlushTexts","GO"); 48 setState("GO", "", 1500); //[ms] 49 } 50 private void setStopState() { 51 Log.d("FlushTexts","STOP"); 52 setState("", "STOP", 4500); //[ms] 53 } 54 private void setClearState() { 55 Log.d("FlushTexts","CLEAR"); 56 setState("", "", 10000); //[ms] 57 } 58 private void setState(String str1, String str2, long delayMillis) { 59 text1.setText(str1); 60 text2.setText(str2); 61 postNext(delayMillis); 62 } 63 synchronized private void postNext(long delayMillis) { 64 if(isRun) handler.postDelayed(this, delayMillis); 65 } 66 } 67 68 @Override 69 protected void onCreate(Bundle savedInstanceState) { 70 super.onCreate(savedInstanceState); 71 setContentView(R.layout.activity_main); 72 73 TextView upview = findViewById(R.id.upview); 74 TextView downview = findViewById(R.id.downview); 75 Button start = findViewById(R.id.start); 76 Button reset = findViewById(R.id.reset); 77 start.setEnabled(true); 78 reset.setEnabled(false); 79 80 FlushTexts flushTexts = new FlushTexts(new Handler(getMainLooper()), upview, downview); 81 82 start.setOnClickListener(view -> { 83 flushTexts.start(); 84 start.setEnabled(false); 85 reset.setEnabled(true); 86 }); 87 88 reset.setOnClickListener(view -> { 89 flushTexts.stop(); 90 upview.setText(""); 91 downview.setText(""); 92 start.setEnabled(true); 93 reset.setEnabled(false); 94 }); 95 } 96}

レイアウト: activity_main.xml

xml

1<?xml version="1.0" encoding="utf-8"?> 2<androidx.constraintlayout.widget.ConstraintLayout 3 xmlns:android="http://schemas.android.com/apk/res/android" 4 xmlns:app="http://schemas.android.com/apk/res-auto" 5 xmlns:tools="http://schemas.android.com/tools" 6 android:layout_width="match_parent" 7 android:layout_height="match_parent" 8 tools:context=".MainActivity"> 9 10 <TextView 11 android:id="@+id/upview" 12 android:layout_width="wrap_content" 13 android:layout_height="wrap_content" 14 android:text="Hello World!" 15 app:layout_constraintBottom_toTopOf="@id/downview" 16 app:layout_constraintLeft_toLeftOf="parent" 17 app:layout_constraintRight_toRightOf="parent" 18 app:layout_constraintTop_toTopOf="parent" /> 19 <TextView 20 android:id="@+id/downview" 21 android:layout_width="wrap_content" 22 android:layout_height="wrap_content" 23 android:text="Hello World!" 24 app:layout_constraintBottom_toTopOf="@id/start" 25 app:layout_constraintLeft_toLeftOf="parent" 26 app:layout_constraintRight_toRightOf="parent" 27 app:layout_constraintTop_toBottomOf="@id/upview" /> 28 <Button 29 android:id="@+id/start" 30 android:layout_width="wrap_content" 31 android:layout_height="wrap_content" 32 android:text="START" 33 app:layout_constraintBottom_toTopOf="@id/reset" 34 app:layout_constraintLeft_toLeftOf="parent" 35 app:layout_constraintRight_toRightOf="parent" 36 app:layout_constraintTop_toBottomOf="@id/downview" /> 37 <Button 38 android:id="@+id/reset" 39 android:layout_width="wrap_content" 40 android:layout_height="wrap_content" 41 android:text="RESET" 42 app:layout_constraintBottom_toBottomOf="parent" 43 app:layout_constraintLeft_toLeftOf="parent" 44 app:layout_constraintRight_toRightOf="parent" 45 app:layout_constraintTop_toBottomOf="@id/start" /> 46 47</androidx.constraintlayout.widget.ConstraintLayout>

scheduleAtFixedRate を使うとこんな感じでしょうか。

java

1package com.teratail.q364882; 2 3import androidx.appcompat.app.AppCompatActivity; 4 5import android.os.*; 6import android.util.Log; 7import android.widget.*; 8 9import java.util.*; 10 11public class MainActivity extends AppCompatActivity { 12 13 private class FlushTexts extends TimerTask { 14 private final Handler handler; 15 private final TextView text1, text2; 16 private int count = 0; 17 18 FlushTexts(Handler handler, TextView text1, TextView text2) { 19 this.handler = handler; 20 this.text1 = text1; 21 this.text2 = text2; 22 } 23 24 @Override 25 public void run() { 26 if(++count >= 12*5+20) { 27 count = 0; //次は Go に行く 28 } else if(count == 12*5+1) { 29 setClearState(); 30 } else if(count <= 12*5) { 31 if(count % 12 == 4) { 32 setStopState(); 33 } else if(count % 12 == 1) { 34 setGoState(); 35 } 36 } 37 } 38 39 private void setGoState() { 40 Log.d("FlushTexts","GO"); 41 setState("GO", ""); 42 } 43 private void setStopState() { 44 Log.d("FlushTexts","STOP"); 45 setState("", "STOP"); 46 } 47 private void setClearState() { 48 Log.d("FlushTexts","CLEAR"); 49 setState("", ""); 50 } 51 private void setState(String str1, String str2) { 52 handler.post(() -> { 53 text1.setText(str1); 54 text2.setText(str2); 55 }); 56 } 57 } 58 59 private Timer timer; 60 61 @Override 62 protected void onCreate(Bundle savedInstanceState) { 63 super.onCreate(savedInstanceState); 64 setContentView(R.layout.activity_main); 65 66 TextView upview = findViewById(R.id.upview); 67 TextView downview = findViewById(R.id.downview); 68 Button start = findViewById(R.id.start); 69 Button reset = findViewById(R.id.reset); 70 start.setEnabled(true); 71 reset.setEnabled(false); 72 73 start.setOnClickListener(view -> { 74 timer = new Timer(); 75 FlushTexts flushTexts = new FlushTexts(new Handler(getMainLooper()), upview, downview); 76 timer.scheduleAtFixedRate(flushTexts, 0, 500); 77 start.setEnabled(false); 78 reset.setEnabled(true); 79 }); 80 81 reset.setOnClickListener(view -> { 82 timer.cancel(); 83 timer = null; 84 upview.setText(""); 85 downview.setText(""); 86 start.setEnabled(true); 87 reset.setEnabled(false); 88 }); 89 } 90}

投稿2021/10/17 12:18

編集2021/10/18 10:15
jimbe

総合スコア13209

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

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

tonyaaa

2021/10/17 12:42

scheduleAtFixedRateの処理を別枠でカウントさせるということでしょうか。
jimbe

2021/10/17 13:33

例えば MyTimer 内で run メソッドが実行される度にカウンタを +1 すれば何回目か分かるわけですね。 ただ、scheduleAtFixedRate などは一定周期の処理に向いているものですので、1.5 秒だったり 4.5 秒だったり 10 秒だったりと頻繁に切り替わる処理には向いていないように思います。 もちろん、最大公約数的に 0.5 秒毎に処理するようにして今何秒目か等で判断することも出来ますが。 任意の時間後に処理を行う Handler.postDelay() を delay を切り替えて使う方法もあります。
tonyaaa

2021/10/18 13:56

とても丁寧にご教示頂きありがとうございます。 また【Handler.postDelay】と【scheduleAtFixedRate】の2パターンで例を示して頂き 大変勉強になります。 私自身、どのような処理が行われているのか理解できていない箇所があり ひとつひとつ調べながら理解していきたいと考えます。 その過程でどうしてもわからない点が出てきましたらまたご相談に乗っていただけたら幸いです。 まずはお礼をしたく、コメント致しました。 本当にありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問