Why does trying to change a TextView or show a toast within a timerTask freeze my app?












1















import android.annotation.SuppressLint
import android.os.Bundle
import android.support.design.widget.Snackbar
import android.support.v7.app.AppCompatActivity;
import android.widget.TextView
import android.widget.Toast
import kotlinx.android.synthetic.main.activity_track_income.*
import java.util.*
import kotlin.concurrent.timerTask

class TrackIncome : AppCompatActivity() {

@SuppressLint("SetTextI18n")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_track_income)

val time: TextView = findViewById(R.id.time)
val money: TextView = findViewById(R.id.money)
val timer: Timer = Timer()
val calculateTime = timerTask {
val milliseconds = System.currentTimeMillis()
var seconds: Int = (milliseconds / 1000).toInt()
val minutes = 1
seconds %= 60
print("seconds are " + seconds.toString())
time.text = String.format("%d.%d", minutes,seconds)

}
Timer("timer", false).schedule(calculateTime,1000, 1000)

}
fun showToast(){
Toast.makeText(this, "Its toast!", Toast.LENGTH_SHORT).show()
}
}


I noticed that if I write time.text within the timerTask object, or try to call showToast(), my app will crash.



Furthermore when I try to comment out
"time.text = String.format("%d.%d", minutes,seconds)" and run the app just using the print statement and examine logcat, the print statement doesn't show up either. I've already read other examples of people using the Timer object, so why doesn't my method work?










share|improve this question

























  • instead of print use Log.d() to view your result.

    – Saurabh Bhandari
    Jan 2 at 4:48
















1















import android.annotation.SuppressLint
import android.os.Bundle
import android.support.design.widget.Snackbar
import android.support.v7.app.AppCompatActivity;
import android.widget.TextView
import android.widget.Toast
import kotlinx.android.synthetic.main.activity_track_income.*
import java.util.*
import kotlin.concurrent.timerTask

class TrackIncome : AppCompatActivity() {

@SuppressLint("SetTextI18n")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_track_income)

val time: TextView = findViewById(R.id.time)
val money: TextView = findViewById(R.id.money)
val timer: Timer = Timer()
val calculateTime = timerTask {
val milliseconds = System.currentTimeMillis()
var seconds: Int = (milliseconds / 1000).toInt()
val minutes = 1
seconds %= 60
print("seconds are " + seconds.toString())
time.text = String.format("%d.%d", minutes,seconds)

}
Timer("timer", false).schedule(calculateTime,1000, 1000)

}
fun showToast(){
Toast.makeText(this, "Its toast!", Toast.LENGTH_SHORT).show()
}
}


I noticed that if I write time.text within the timerTask object, or try to call showToast(), my app will crash.



Furthermore when I try to comment out
"time.text = String.format("%d.%d", minutes,seconds)" and run the app just using the print statement and examine logcat, the print statement doesn't show up either. I've already read other examples of people using the Timer object, so why doesn't my method work?










share|improve this question

























  • instead of print use Log.d() to view your result.

    – Saurabh Bhandari
    Jan 2 at 4:48














1












1








1








import android.annotation.SuppressLint
import android.os.Bundle
import android.support.design.widget.Snackbar
import android.support.v7.app.AppCompatActivity;
import android.widget.TextView
import android.widget.Toast
import kotlinx.android.synthetic.main.activity_track_income.*
import java.util.*
import kotlin.concurrent.timerTask

class TrackIncome : AppCompatActivity() {

@SuppressLint("SetTextI18n")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_track_income)

val time: TextView = findViewById(R.id.time)
val money: TextView = findViewById(R.id.money)
val timer: Timer = Timer()
val calculateTime = timerTask {
val milliseconds = System.currentTimeMillis()
var seconds: Int = (milliseconds / 1000).toInt()
val minutes = 1
seconds %= 60
print("seconds are " + seconds.toString())
time.text = String.format("%d.%d", minutes,seconds)

}
Timer("timer", false).schedule(calculateTime,1000, 1000)

}
fun showToast(){
Toast.makeText(this, "Its toast!", Toast.LENGTH_SHORT).show()
}
}


I noticed that if I write time.text within the timerTask object, or try to call showToast(), my app will crash.



Furthermore when I try to comment out
"time.text = String.format("%d.%d", minutes,seconds)" and run the app just using the print statement and examine logcat, the print statement doesn't show up either. I've already read other examples of people using the Timer object, so why doesn't my method work?










share|improve this question
















import android.annotation.SuppressLint
import android.os.Bundle
import android.support.design.widget.Snackbar
import android.support.v7.app.AppCompatActivity;
import android.widget.TextView
import android.widget.Toast
import kotlinx.android.synthetic.main.activity_track_income.*
import java.util.*
import kotlin.concurrent.timerTask

class TrackIncome : AppCompatActivity() {

@SuppressLint("SetTextI18n")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_track_income)

val time: TextView = findViewById(R.id.time)
val money: TextView = findViewById(R.id.money)
val timer: Timer = Timer()
val calculateTime = timerTask {
val milliseconds = System.currentTimeMillis()
var seconds: Int = (milliseconds / 1000).toInt()
val minutes = 1
seconds %= 60
print("seconds are " + seconds.toString())
time.text = String.format("%d.%d", minutes,seconds)

}
Timer("timer", false).schedule(calculateTime,1000, 1000)

}
fun showToast(){
Toast.makeText(this, "Its toast!", Toast.LENGTH_SHORT).show()
}
}


I noticed that if I write time.text within the timerTask object, or try to call showToast(), my app will crash.



Furthermore when I try to comment out
"time.text = String.format("%d.%d", minutes,seconds)" and run the app just using the print statement and examine logcat, the print statement doesn't show up either. I've already read other examples of people using the Timer object, so why doesn't my method work?







android kotlin






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Jan 2 at 4:42









Android

805420




805420










asked Jan 2 at 4:38









okmanlokmanl

747




747













  • instead of print use Log.d() to view your result.

    – Saurabh Bhandari
    Jan 2 at 4:48



















  • instead of print use Log.d() to view your result.

    – Saurabh Bhandari
    Jan 2 at 4:48

















instead of print use Log.d() to view your result.

– Saurabh Bhandari
Jan 2 at 4:48





instead of print use Log.d() to view your result.

– Saurabh Bhandari
Jan 2 at 4:48












2 Answers
2






active

oldest

votes


















2














Timer object is a single background thread So it cannot access UI elements (like toast, textview) directly.
reference




Why your app is freezing out?




Timer tasks should complete quickly. If a timer task takes excessive time to complete, it "hogs" the timer's task execution thread. This can, in turn, delay the execution of subsequent tasks, which may "bunch up" and execute in rapid succession when (and if) the offending task finally completes.



Best approach for above would be using a handler, after timer completes. Like,



    private Handler handler = new Handler();


and define it



handler = new Handler(getLooper()) {
@Override
public void handleMessage(Message msg) {
Toast.makeText(this, "Its toast!", Toast.LENGTH_SHORT).show();
}
};


invoke it from your timer :




handler.sendMessage(messageObject);






share|improve this answer































    1














    Toast is a UI element so it needs to run on the UI Thread, not in a background Thread



    use runOnUiThread



    runOnUiThread(new Runnable() {
    public void run()
    {
    Toast.makeText(yourContext, "Your Message", Toast.LENGTH_SHORT).show();
    }
    });
    }





    share|improve this answer

























      Your Answer






      StackExchange.ifUsing("editor", function () {
      StackExchange.using("externalEditor", function () {
      StackExchange.using("snippets", function () {
      StackExchange.snippets.init();
      });
      });
      }, "code-snippets");

      StackExchange.ready(function() {
      var channelOptions = {
      tags: "".split(" "),
      id: "1"
      };
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function() {
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled) {
      StackExchange.using("snippets", function() {
      createEditor();
      });
      }
      else {
      createEditor();
      }
      });

      function createEditor() {
      StackExchange.prepareEditor({
      heartbeatType: 'answer',
      autoActivateHeartbeat: false,
      convertImagesToLinks: true,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      bindNavPrevention: true,
      postfix: "",
      imageUploader: {
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      },
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      });


      }
      });














      draft saved

      draft discarded


















      StackExchange.ready(
      function () {
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54001258%2fwhy-does-trying-to-change-a-textview-or-show-a-toast-within-a-timertask-freeze-m%23new-answer', 'question_page');
      }
      );

      Post as a guest















      Required, but never shown

























      2 Answers
      2






      active

      oldest

      votes








      2 Answers
      2






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      2














      Timer object is a single background thread So it cannot access UI elements (like toast, textview) directly.
      reference




      Why your app is freezing out?




      Timer tasks should complete quickly. If a timer task takes excessive time to complete, it "hogs" the timer's task execution thread. This can, in turn, delay the execution of subsequent tasks, which may "bunch up" and execute in rapid succession when (and if) the offending task finally completes.



      Best approach for above would be using a handler, after timer completes. Like,



          private Handler handler = new Handler();


      and define it



      handler = new Handler(getLooper()) {
      @Override
      public void handleMessage(Message msg) {
      Toast.makeText(this, "Its toast!", Toast.LENGTH_SHORT).show();
      }
      };


      invoke it from your timer :




      handler.sendMessage(messageObject);






      share|improve this answer




























        2














        Timer object is a single background thread So it cannot access UI elements (like toast, textview) directly.
        reference




        Why your app is freezing out?




        Timer tasks should complete quickly. If a timer task takes excessive time to complete, it "hogs" the timer's task execution thread. This can, in turn, delay the execution of subsequent tasks, which may "bunch up" and execute in rapid succession when (and if) the offending task finally completes.



        Best approach for above would be using a handler, after timer completes. Like,



            private Handler handler = new Handler();


        and define it



        handler = new Handler(getLooper()) {
        @Override
        public void handleMessage(Message msg) {
        Toast.makeText(this, "Its toast!", Toast.LENGTH_SHORT).show();
        }
        };


        invoke it from your timer :




        handler.sendMessage(messageObject);






        share|improve this answer


























          2












          2








          2







          Timer object is a single background thread So it cannot access UI elements (like toast, textview) directly.
          reference




          Why your app is freezing out?




          Timer tasks should complete quickly. If a timer task takes excessive time to complete, it "hogs" the timer's task execution thread. This can, in turn, delay the execution of subsequent tasks, which may "bunch up" and execute in rapid succession when (and if) the offending task finally completes.



          Best approach for above would be using a handler, after timer completes. Like,



              private Handler handler = new Handler();


          and define it



          handler = new Handler(getLooper()) {
          @Override
          public void handleMessage(Message msg) {
          Toast.makeText(this, "Its toast!", Toast.LENGTH_SHORT).show();
          }
          };


          invoke it from your timer :




          handler.sendMessage(messageObject);






          share|improve this answer













          Timer object is a single background thread So it cannot access UI elements (like toast, textview) directly.
          reference




          Why your app is freezing out?




          Timer tasks should complete quickly. If a timer task takes excessive time to complete, it "hogs" the timer's task execution thread. This can, in turn, delay the execution of subsequent tasks, which may "bunch up" and execute in rapid succession when (and if) the offending task finally completes.



          Best approach for above would be using a handler, after timer completes. Like,



              private Handler handler = new Handler();


          and define it



          handler = new Handler(getLooper()) {
          @Override
          public void handleMessage(Message msg) {
          Toast.makeText(this, "Its toast!", Toast.LENGTH_SHORT).show();
          }
          };


          invoke it from your timer :




          handler.sendMessage(messageObject);







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Jan 2 at 5:41









          Anu BhallaAnu Bhalla

          425311




          425311

























              1














              Toast is a UI element so it needs to run on the UI Thread, not in a background Thread



              use runOnUiThread



              runOnUiThread(new Runnable() {
              public void run()
              {
              Toast.makeText(yourContext, "Your Message", Toast.LENGTH_SHORT).show();
              }
              });
              }





              share|improve this answer






























                1














                Toast is a UI element so it needs to run on the UI Thread, not in a background Thread



                use runOnUiThread



                runOnUiThread(new Runnable() {
                public void run()
                {
                Toast.makeText(yourContext, "Your Message", Toast.LENGTH_SHORT).show();
                }
                });
                }





                share|improve this answer




























                  1












                  1








                  1







                  Toast is a UI element so it needs to run on the UI Thread, not in a background Thread



                  use runOnUiThread



                  runOnUiThread(new Runnable() {
                  public void run()
                  {
                  Toast.makeText(yourContext, "Your Message", Toast.LENGTH_SHORT).show();
                  }
                  });
                  }





                  share|improve this answer















                  Toast is a UI element so it needs to run on the UI Thread, not in a background Thread



                  use runOnUiThread



                  runOnUiThread(new Runnable() {
                  public void run()
                  {
                  Toast.makeText(yourContext, "Your Message", Toast.LENGTH_SHORT).show();
                  }
                  });
                  }






                  share|improve this answer














                  share|improve this answer



                  share|improve this answer








                  edited Jan 2 at 5:56









                  Rumit Patel

                  1,86852536




                  1,86852536










                  answered Jan 2 at 5:16









                  Rohit ChauhanRohit Chauhan

                  587417




                  587417






























                      draft saved

                      draft discarded




















































                      Thanks for contributing an answer to Stack Overflow!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function () {
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54001258%2fwhy-does-trying-to-change-a-textview-or-show-a-toast-within-a-timertask-freeze-m%23new-answer', 'question_page');
                      }
                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      Popular posts from this blog

                      MongoDB - Not Authorized To Execute Command

                      in spring boot 2.1 many test slices are not allowed anymore due to multiple @BootstrapWith

                      How to fix TextFormField cause rebuild widget in Flutter