Android - running a method periodically using postDelayed() call

强颜欢笑 提交于 2019-11-26 08:59:51

问题


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).


回答1:


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()




回答2:


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);



回答3:


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.




回答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)



回答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);



回答6:


Handler h = new Handler() {
    @Override
    public void handleMessage(Message msg) {
        super.handleMessage(msg);
        if (msg.what==0){
            // do stuff
            h.removeMessages(0);  // clear the handler for those messages with what = 0
            h.sendEmptyMessageDelayed(0, 2000); 
        }
    }
};


 h.sendEmptyMessage(0);  



回答7:


I think you could experiment with different activity flags, as it sounds like multiple instances.

"singleTop" "singleTask" "singleInstance"

Are the ones I would try, they can be defined inside the manifest.

http://developer.android.com/guide/topics/manifest/activity-element.html




回答8:


You should set andrid:allowRetainTaskState="true" to Launch Activity in Manifest.xml. If this Activty is not Launch Activity. you should set android:launchMode="singleTask" at this activity



来源:https://stackoverflow.com/questions/10845172/android-running-a-method-periodically-using-postdelayed-call

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!