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

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

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

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

Android Studio

Android Studioは、 Google社によって開発された、 Androidのネイティブアプリケーション開発に特化した統合開発ツールです。

Q&A

1回答

636閲覧

スマホにアプリを表示後に、スレッドを動かしたい。

aruko

総合スコア47

Java

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

Android Studio

Android Studioは、 Google社によって開発された、 Androidのネイティブアプリケーション開発に特化した統合開発ツールです。

0グッド

0クリップ

投稿2021/12/03 00:27

編集2021/12/03 06:03

下のようにthreadを使って、countを表示していますが、実行完了後count++が始まります。
実行完了後(インストール完了後)だと、スマホを開いていなくてもcount++が始まってしまいます。
スマホでアプリを表示後にcount++を始めるには、どのようにしたらよいでしょうか。
よろしくお願いします。

説明を詳細にします。

実行完了後というのは、android studioでビルドが終わりインストールが終わった後に「操作が正常に完了しました」というメッセージが出た時、という意味です。
その時にスマホを開いていれば、そのアプリが表示され、countが0からカウントされますが、しばらくしてからスマホの電源を入れてアプリを表示させると、すでにcountがかなり進んだ状態で表示されます。
なので、スマホの電源を入れてアプリを表示させたときにcountが0からカウントされるようにしたいです。

java

1 2import android.animation.AnimatorInflater; 3import android.animation.AnimatorSet; 4import android.graphics.Insets; 5import android.os.Bundle; 6import android.os.Handler; 7import android.os.Looper; 8import android.view.*; 9import android.view.animation.Animation; 10import android.view.animation.AnimationUtils; 11import android.widget.ImageView; 12import android.widget.TextView; 13 14import androidx.annotation.*; 15import androidx.constraintlayout.widget.ConstraintLayout; 16import androidx.constraintlayout.widget.ConstraintSet; 17import androidx.fragment.app.Fragment; 18import androidx.lifecycle.ViewModelProvider; 19 20import static tmaruko.okura.jiisan.MainActivity.anim1; 21import static tmaruko.okura.jiisan.MainActivity.anim_idou_migi; 22 23 24public class MainFragment extends Fragment implements Runnable{ 25 TextView frma_tv1; 26 TextView frma_tv2; 27 TextView frma_tv3; 28 TextView frma_tv4; 29 TextView frma_tv5; 30 TextView frma_tv6; 31 TextView frma_tv7; 32 TextView frma_tv8; 33 ImageView kaki1; 34 ImageView saru; 35 int count; 36 Thread thread; 37 38 @Override 39 public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 40 return inflater.inflate(R.layout.fragment_main, container, false); 41 42 } 43 44 @Override 45 public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { 46 super.onViewCreated(view, savedInstanceState); 47 48 MainViewModel vm = new ViewModelProvider(requireActivity()).get(MainViewModel.class); 49 thread=new Thread(this); 50 count=0; 51 saru=view.findViewById(R.id.saru); 52 kaki1=view.findViewById(R.id.kaki1); 53 frma_tv1=view.findViewById(R.id.frma_tv1); 54 frma_tv2=view.findViewById(R.id.frma_tv2); 55 frma_tv3=view.findViewById(R.id.frma_tv3); 56 frma_tv4=view.findViewById(R.id.frma_tv4); 57 frma_tv5=view.findViewById(R.id.frma_tv5); 58 frma_tv6=view.findViewById(R.id.frma_tv6); 59 frma_tv7=view.findViewById(R.id.frma_tv7); 60 frma_tv8=view.findViewById(R.id.frma_tv8); 61 62 ConstraintLayout.LayoutParams layoutparams = (ConstraintLayout.LayoutParams)kaki1.getLayoutParams(); 63 float f=layoutparams.horizontalBias; 64 frma_tv7.setText(String.valueOf(f)); 65 frma_tv8.setText("count="+String.valueOf(count)); 66 thread.start(); 67 } 68 69 public void start(){ 70 if(thread==null){ 71 thread=new Thread(this); 72 thread.start(); 73 } 74 } 75 76 public void stop(){ 77 if(thread!=null){thread=null;} 78 } 79 80 public void run() { 81 Thread thisThread=Thread.currentThread(); 82 final Handler mainHandler = new Handler(Looper.getMainLooper()); 83 while (thread!=null){ 84 count++; 85 mainHandler.post(() -> { 86 frma_tv8.setText("count=" + String.valueOf(count)); 87 if(count==1){frma_tv1.startAnimation(anim1);} 88 else if(count==5){frma_tv2.startAnimation(anim1);} 89 else if(count==9){frma_tv3.startAnimation(anim1);} 90 else if(count==13){ 91 frma_tv4.startAnimation(anim1); 92 saru.startAnimation(anim_idou_migi); 93 } 94 else if(count==17){frma_tv5.startAnimation(anim1);} 95 }); 96 try { 97 thread.sleep(1000); 98 } catch (InterruptedException e) { 99 } 100 } 101 } 102} 103 104

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

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

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

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

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

jimbe

2021/12/03 03:15 編集

「実行完了後」とは、どういうタイミングでしょうか。 大抵はアプリが終了することを「実行が終わる」と言うように思いますが、それであっていますでしょうか。 「スマホを開いていなくても」というのも、プログラムから見てどういう状況なのかが分かりません。 ディスプレイが off になっているということでしょうか。 もう少し状況を整理して頂いて、プログラム視点からの説明を頂けると良いかと思います。 言葉での説明よりも実行してみたほうが分かり易いようであれば、実行できる一式(状況が再現するに最低限必要なコードやレイアウト・設定ファイル等)をご用意頂けると助かります。
jimbe

2021/12/03 10:17

> android studioでビルドが終わりインストールが終わった後に「操作が正常に完了しました」というメッセージが出た時 それは AndroidStudio からのメッセージということでしょうか。 つまり「ツールが」正常に完了したのであって、「アプリとしては」逆に実行を開始したということですね。 AndroidStudio 上で実行操作をしているのであれば、インストール後アプリが実行されるのは当然と思いますが、実行操作をしていないのでしょうか。
aruko

2021/12/03 10:55

androidstudio上で(エミュレータ)実行するのではなく、すべて実機、自分のスマホで実行させています。 よろしくお願いします。
jimbe

2021/12/03 15:19

エミュレータでも実機でも実行は同じことです。というか、同じで無ければエミュレータの意味がありません。 そして、すいません少し勘違いしていました。start() / stop() メソッドはライフサイクルの onStart() / onStop() メソッドではありませんので、ご提示のコードでは全く実行されないですね。 スレッドの実行は onViewCreated での thread.start(); だけですので、アプリが実行され次第カウントがスタートし、それ以降何もされていないので実行し続けているということのようです。
guest

回答1

0

しばらくしてからスマホの電源を入れてアプリを表示させると、すでにcountがかなり進んだ状態で表示されます。

スレッドが停止していないということですね。
stop() での thread 変数の null 化の に、スレッドに対して割り込みをかけて sleep を抜けさせ、 while (thread!=null) を通って停止するまで join して確実にスレッドを止まったことを確認したほうが良いのではないでしょうか。
また、MainLoop に post した処理がまだ未処理で残っている場合もありますので、出来ればそれをキャンセルするべきかもしれませんが…現状ではそのオブジェクトは作りっぱなしですので修正が大変かもしれません。

少し勘違いしていました。すいません。
start() / stop() メソッドはライフサイクルの onStart() / onStop() メソッドではありませんので、ご提示のコードでは全く実行されないですね。
onStart()/ onStop() であれば(手元で実際に確認した所では)実機のスクリーンが off の状態で AndroidStudio で実行すると onStart() の後即 onStop() 実行されますので、 onStart でスレッドを開始し onStop でスレッドを停止させれば、スクリーン off 時はカウントが止まり、スクリーン on でまたカウントするようになると思います。

スクリーン on でまた 0 からカウントするのであれば、 onStart で count = 0 してからスレッドを開始すれば良いかと思います。


次のようなコードにすれば、実行時のプログラムの動作が logcat に出ますので、画面を off にしてみたりして確認してみてください。
Handler で post するオブジェクトを念の為 remove するようにし、 count をタイマーのスレッドに定義することで再始動時の count のリセットとしています。
スレッドの停止も interrupt に対応しました。

(EmptyActivity から作ったプロジェクトで、 Hello World! を表示していた TextView に android:id="@+id/textView" を加えて使っています。)

java

1package com.teratail.q372044; 2 3import androidx.appcompat.app.AppCompatActivity; 4 5import android.os.*; 6import android.util.Log; 7import android.widget.TextView; 8 9public class MainActivity extends AppCompatActivity implements Runnable { 10 private Thread thread; 11 private Handler mainHandler = new Handler(Looper.getMainLooper()); 12 private TextView textView; 13 14 @Override 15 protected void onCreate(Bundle savedInstanceState) { 16 super.onCreate(savedInstanceState); 17 setContentView(R.layout.activity_main); 18 19 textView = findViewById(R.id.textView); 20 21 start(); 22 } 23 24 @Override 25 protected void onStart() { 26 Log.d("MainActivity","onStart()"); 27 super.onStart(); 28 start(); 29 } 30 31 @Override 32 protected void onStop() { 33 Log.d("MainActivity","onStop()"); 34 super.onStop(); 35 stop(); 36 } 37 38 public void start(){ 39 Log.d("MainActivity","start()"); 40 if(thread == null){ 41 thread = new Thread(this); 42 Log.d("MainActivity","thread start."); 43 thread.start(); 44 } 45 } 46 47 public void stop(){ 48 Log.d("MainActivity","stop()"); 49 if(thread != null) { 50 thread.interrupt(); 51 try { 52 thread.join(); 53 Log.d("MainActivity","thread join."); 54 } catch (InterruptedException ignore) { 55 } 56 thread = null; 57 } 58 } 59 60 private class CountCallback implements Runnable { 61 private int count; 62 CountCallback(int count) { 63 this.count = count; 64 } 65 @Override 66 public void run() { 67 textView.setText("count=" + count); 68 Log.d("MainActivity","CountAction count="+count); 69 } 70 } 71 72 @Override 73 public void run() { 74 Thread thisThread = Thread.currentThread(); 75 Log.d("MainActivity","run() start. "+thisThread); 76 int count = 0; 77 for(boolean stop=false; !stop; ) { 78 CountCallback countCallback = new CountCallback(++count); 79 mainHandler.post(countCallback); 80 try { 81 thisThread.sleep(1000); 82 } catch (InterruptedException e) { 83 stop = true; 84 } 85 mainHandler.removeCallbacks(countCallback); //念の為 86 } 87 Log.d("MainActivity","run() stop. "+thisThread); 88 } 89}

投稿2021/12/03 10:09

編集2021/12/03 19:26
jimbe

総合スコア12646

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問