Android - running a method periodically using postDelayed() call

I have a situation in an Android app where I want to start a network activity (sending out some data) which should run every second. I achieve this as follows:

In the onCreate() I have the code:

tv = new TextView(this);
tv.postDelayed(sendData, 1000);

The sendData() function:

   Handler handler = new Handler();
   private Runnable sendData=new Runnable(){
    public void run(){
        try {
            //prepare and send the data here..
            handler.removeCallbacks(sendData);
            handler.postDelayed(sendData, 1000);    
        }
        catch (Exception e) {
            e.printStackTrace();
        }   
    }
};

The problem come in like this: When user presses the back buttons and app comes out (UI disappears) the sendData() function still gets executed which is what I want. Now when user re-starts the app, my onCreate() gets called again and I get sendData() invoked twice a second. It goes on like that. Every time user comes out and starts again, one more sendData() per second happens.

What am I doing wrong? Is it my new Handler() creating problem? What is the best way to handle this? I want one sendData() call per second until user quits the app (form application manager).


Solution 1:

final Handler handler = new Handler();
    handler.postDelayed(new Runnable() {
      @Override
      public void run() {
        //Do something after 100ms
        Toast.makeText(c, "check", Toast.LENGTH_SHORT).show();  
        handler.postDelayed(this, 2000);
      }
    }, 1500);

Solution 2:

Perhaps involve the activity's life-cycle methods to achieve this:

Handler handler = new Handler();

@Override
protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      handler.post(sendData);
}

@Override
protected void onDestroy() {
      super.onDestroy();
      handler.removeCallbacks(sendData);
}


private final Runnable sendData = new Runnable(){
    public void run(){
        try {
            //prepare and send the data here..


            handler.postDelayed(this, 1000);    
        }
        catch (Exception e) {
            e.printStackTrace();
        }   
    }
};

In this approach, if you press back-key on your activity or call finish();, it will also stop the postDelayed callings.

Solution 3:

Why don't you create service and put logic in onCreate(). In this case even if you press back button service will keep on executing. and once you enter into application it will not call onCreate() again. Rather it will call onStart()

Solution 4:

You can simplify the code like this.

In Java:

new Handler().postDelayed (() -> {
    //your code here
}, 1000);

In Kotlin:

Handler().postDelayed({
   //your code here
}, 1000)

Solution 5:

Please check the below its working on my side in below code your handler will run after every 1 Second when you are on same activity

 HandlerThread handlerThread = new HandlerThread("HandlerThread");
                handlerThread.start();
                handler = new Handler(handlerThread.getLooper());
                runnable = new Runnable()
                {
                    @Override
                    public void run()
                    {

                            handler.postDelayed(this, 1000);
                        }
                };
                handler.postDelayed(runnable, 1000);