I have been using handler inside service class, the handler is responsible for sending location every 5 seconds via socket. When logging out, the service gets stopped but the handler still running.
I tried every possible way, By using any boolean variable is not feasible in my case because i have to start again that handler.
public Runnable mn_Runnable12 = new Runnable() {
public void run() {
gps = new GPSTracker(LocationService.this);
if (gps.canGetLocation()) {
latString = Double.toString(gps.getLatitude()); // Live
logString = Double.toString(gps.getLongitude());
connection= MyApplication.getInstance().getConnection();
if (connection!=null&&connection.isConnected()) {
sendLocation();
}
}
}
};
this is inside onCreate() of service.
T.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
mHandler12.postDelayed(mn_Runnable12, 5000);
}
},
5000,
5000);
I try to stop the handler in onDestroy method of service, service gets topped but the handler still running.
#Override
public void onDestroy() {
System.out.println("Location Service Detaroy-----");
if (connection.isConnected()) {
unSubscribe();
}
mHandler12.removeCallbacksAndMessages(null);
mHandler10.removeCallbacksAndMessages(null);
}
You Also have to cancel Timer Since its running repeatedly with an interval.
First cancel timer and then remove handlers callback.
T.cancel();
T.purge();
// remove handler here
Related
I created one handler to repeat a task repeatedly and I also want to destroy it within that handler once a condition has been met.
pinHandler = new Handler();
Now I created two functions separately to start and stop the task.
void startRepeatingPins() {
mPinSetter.run();
}
Runnable mPinSetter = new Runnable() {
#Override
public void run() {
try{
System.out.println("PinIndwx count is :"+pinIndexCount);
if(pinIndexCount==(plist.size()-1))
{
stopUpdatingPins();
pinIndexCount=0;
//pinHandler.removeCallbacks(mPinSetter);
System.out.println("Handler stopped by itself.");
}
else
{
updatePoint(plist.get(pinIndexCount));
pinIndexCount++;
}
}
finally {
pinHandler.postDelayed(mPinSetter, pinInterval);
}
}
};
private void stopUpdatingPins()
{
pinIndexCount=0;
pinHandler.removeCallbacks(mPinSetter);
System.out.println("Called the stop function.");
}
Now, the issue is that, if I call the stopUpdatingPins function , the handler stops but when I try to stop it automatically from within the handler, it just doesn't stop. Although the stopUpdatingPins function does get called.
Change You startRepeatingPins() like this, You should not directly call the run. If your run like this then there is no point of removing this from Handler. So attach Runnable with Handler.
void startRepeatingPins() {
pinHandler.post(mPinSetter);
}
You added post delay in finally that means you are stopping at first if loop and starting again in finally, So it's never stopping. So Change your runnable like this,
Runnable mPinSetter = new Runnable() {
#Override
public void run() {
System.out.println("PinIndwx count is :"+pinIndexCount);
if(pinIndexCount==(plist.size()-1))
{
stopUpdatingPins();
pinIndexCount=0;
//pinHandler.removeCallbacks(mPinSetter);
System.out.println("Handler stopped by itself.");
}
else
{
updatePoint(plist.get(pinIndexCount));
pinIndexCount++;
pinHandler.postDelayed(mPinSetter, pinInterval);
}
}
};
I need to repeat a task every 1 hour in the background (I am sending some info to my server).
I tried to use a service with a post delay handler calling it self.
handler = new Handler();
runable = new Runnable() {
#Override
public void run() {
try{
//sending info to server....
}
catch (Exception e) {
// TODO: handle exception
}
finally{
//also call the same runnable
handler.postDelayed(this, 1000*60*60);
}
}
};
handler.postDelayed(runable, 1000*60*60);
This did not work, in small time interval of 1 minutes it worked fine, when i changed it to 5 minutes it worked for about 5 repetitions and then the timing got wrong and after an hour the service shut down.
i want to try to use a AlarmManager but in the documentation
it says "As of Android 4.4 (API Level 19), all repeating alarms are inexact"
does anybody know how inexact it is? is it seconds? ,minutes?
can i rely on this to work on time?
does anybody have any other suggestions for repeating tasks in a service?
Thanks
You can use this This Code is for repeated calling on oncreate method or anyother thing
public void callAsynchronousTask() {
final Handler handler = new Handler();
Timer timer = new Timer();
TimerTask doAsynchronousTask = new TimerTask() {
#Override
public void run() {
handler.post(new Runnable() {
public void run() {
try {
onCreate();
} catch (Exception e) {
}
}
});
}
};
timer.schedule(doAsynchronousTask, 0, 1000); //execute in every 1000 ms
}
I would like to periodically check for updates doing network call every 30 sec and update listview accordingly, only if my screen is in foreground (thus not from service). What I am doing for that is -
private void refreshPeriodically()
{
final Handler handler = new Handler();
Timer timer = new Timer();
TimerTask doAsynchronousTask = new TimerTask() {
#Override
public void run() {
handler.post(new Runnable() {
public void run() {
try {
new callToMyAsyncTask().execute(context);
} catch (Exception e) {
// TODO Auto-generated catch block
}
}
});
}
};
timer.schedule(doAsynchronousTask, 0, 30*1000); //execute in every 30 sec
}
but, that hangs my list while scrolling.
What should I do for that?
You shouldn't use handler. When you call handler.post() it will run on UI thread so your list will freeze. Start a new callToMyAsyncTask in run method in TimerTask without using handler and you can call timer.cancel() when your activity is not in foreground.
Also I think you should use scheduleAtFixedRate instead of schedule.
However I think you may have some problems without service. When you cancel timer it will not cancel current callToMyAsyncTask and when it call onPostExecute activity is no longer available. But I don't know it will crash or not.
public void displayCurrentLocation(){
mCurrentLocation=mLocationClient.getLastLocation();
TextView coordinates = (TextView)findViewById(R.id.coordinates);
coordinates.setText(mCurrentLocation.getLatitude()+", "+mCurrentLocation.getLongitude());
Timer timer = new Timer();
timer.schedule(new TimerTask() {
#Override
public void run() {
displayCurrentLocation();
}
}, 2000);
}
Just testing the concepts here. I am trying to get an updated current location every 2 seconds and display it in a TextView. I set this up so that it would do it once, but when I added the timer, it will setText once, but the next time it crashes. What is wrong?
I am trying to get an updated current location every 2 seconds and display it in a TextView.
My guess (based on above comment) is you are updating ui from a Timer task. Timer tasks runs on a different thread. You can't update ui from it. You need to update ui from a ui thread.
Use a Handler or runOnUiThread
runOnUiThread(new Runnable() {
public void run() {
// update ui here
}
});
Handler is a better option.
http://developer.android.com/reference/android/os/Handler.html
When you create a new Handler, it is bound to the thread / message queue of the thread that is creating it -- from that point on, it will deliver messages and runnables to that message queue and execute them as they come out of the message queue.
So if you create handler on the ui thread it is bound to it and you can update ui there.
Handler m_handler;
Runnable m_handlerTask ;
int timeleft=100;
m_handler = new Handler();
m_handlerTask = new Runnable()
{
#Override
public void run() {
// do something
m_handler.postDelayed(m_handlerTask, 2000);
}
};
m_handlerTask.run();
To cancel the run
m_handler.removeCallbacks(m_handlerTask); // cancel run
Timer runs in a separate Thread and where as you can not touch the UI views in non UI Thread...
use Handler of a TextView or runOnUiThread()
this may help you...
public void displayCurrentLocation() {
mCurrentLocation = mLocationClient.getLastLocation();
runOnUiThread(new Runnable() {
#Override
public void run() {
TextView coordinates = (TextView) findViewById(R.id.coordinates);
coordinates.setText(mCurrentLocation.getLatitude() + ", "
+ mCurrentLocation.getLongitude());
}
});
Timer timer = new Timer();
timer.schedule(new TimerTask() {
#Override
public void run() {
displayCurrentLocation();
}
}, 2000);
I have an activity that vibrates the phone for 9 seconds after it starts. I want the vibration action to be canceled when the activity leaves the foreground. Here is my current code:
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
// change image
screen.setImageResource(R.drawable.yama);
vibrateMe();
}
}, 9000);
}
public void vibrateMe() {
Vibrator vibrate = (Vibrator)getSystemService(Context.VIBRATOR_SERVICE);
vibrate.vibrate(2000);
}
public void stopVibrating(Vibrator vibrate) {
vibrate.cancel();
}
#Override
public void onDestroy() {
super.onDestroy();
}
}
You want to cancel your runnable?
There are 2 options:
you can cancel all your delayed runnables with handler.removeCallbacksAndMessages(null)
you should save ref to runnable (Runnable vibrateRunnable = new Runnable() ... ) and then remove it if needed with handler.removeCallbacks(vibrateRunnable)
You can cancel all CallBacks and Messages using removeCallbacksAndMessages();
public final void removeCallbacksAndMessages (Object token)
Added in API level 1
Remove any pending posts of callbacks and sent messages whose obj is token. If token is null, all callbacks and messages will be removed.