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).
This question is related to
android
postdelayed
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);
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);
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
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);
You can simplify the code like this.
In Java:
new Handler().postDelayed (() -> {
//your code here
}, 1000);
In Kotlin:
Handler().postDelayed({
//your code here
}, 1000)
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.
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
Source: Stackoverflow.com