I'm developing an application that should execute some task periodically (10 seconds) in the background. For this I use Service and Timer. Actual jobs to be done in timer are:
1) collecting data from the phone (using ContentResolver) into the SQLite database,
2) sending this data to remote server synchronously using HttpPost method.
The problem is next: after some iterations (ammount of these iterations changes every execution of the app) timer changes its period and start to perform all the tasks with 1-3 seconds (sometimes up to 9, but it always lower than 10 secs) delay, which is way too fast in my case and I can't find the reason.
Has anyone faced similar behavior before?
I've tried to use different threads for uploading and collecting inside the timer task, but it didn't solve the problem.
Here's my code snippets:
public class DataForward extends Service{
private Context con = getBaseContext();
private Timer timer = new Timer();
<...>
#Override
public void onStart(Intent intent, int startId) {
timer.schedule(new TimerTask(){
#Override
public void run() {
try {
updateData();
NetworkManager network = new NetworkManager(con);
if(network.isConnectedToTheInternet())
uploadData();
} catch (Exception e) {
e.printStackTrace();
}
}}, 0, 10000);
}
}
<...>
}
Or maybe there's another way to do this without actual Timer?
Any Ideas?
The reason could be, since you told its running on a service, its so possible that your
backgroundTask(Service) may get killed when android OS finds its going low on RAM inorder to keep its
foreGround Applications running.. And again when it gets Free Ram it Restarts the Service Again, so
it may be restarting timer again and again.
for more Read THis ..SERVICE
First execution of your time is 0 millis and subsequent execution is after 10 millis.But android os may stop your service for internal task management.So,again when your service start s after some time then it reset timer again.So,it will execute your task immediately.thats the reason of your problem.
So you can set a time minimum time for your first execution or can use repeating Alarm.
Related
I am using Java executorservice to create a timeout effect in one of my apps. After an elapsed time, they executor service begins and logs the user out of their session. But on an Android device when the device goes to sleep the executor thread is suspended. After the device awakes the thread is unsuspended. I would like the change the clock the executor is using so that it continues counting even after the device goes to deep sleep. Is there no way I can over ride which clock is being used (I realize I can swap out the entire implementation and use alarmmanager but I'm looking to not alter existing code at this point so please do not try to offer other APIs).
My question is, there must be a system clock that keeps going despite the device being asleep, how can I let the executor scheduler use that clock instead of the one it's using now which respects the device going to deep sleep and pauses ticking?
My code I have currently is very simple and just looks like this:
myExecutorService.schedule(new EndUserSession(),
6L, TimeUnit.MINUTES);
this code above starts the EndUserSession() in 6 minutes. It works but I want to use another clock that does not respect time out of mobile device.
I have strong doubts that it's possible to influence scheduler service timing mechanisms.
You have another option to avoid problems caused by device sleep, like passing specific timestamp in constructor and scheduling a task at fixed rate. Example:
class EndSessionTask {
final long sessionExpirationTime;
volatile ScheduledFuture future;
public EndSessionTask(long ts) { sessionExpirationTime = ts; }
public void run() {
if (sessionExpirationTime < currentTs) return;
endSession();
future.cancel();
}
public void setFuture(ScheduledFuture f) { this.future = f; }
}
long endSessionTime = System.currentTimeMillis() + 6 * 60 * 1000;
EndSessionTask task = new EndSessionTask(endSessionTime);
ScheduledFuture future = executorService.scheduleAtFixedRate(task, 10L, 10L, SECONDS);
task.setFuture(future);
I'm experiencing a strange behavior on my Android app.
I want to schedule a fixed-rate operation that saves the properties of a "player" object. During the application flow, the user may change it's settings but the saving is performed every 2 minutes by this little task.
The task is run by a static ScheduledExecutorService, initialized when the app starts:
private static ScheduledExecutorService threadExecutor;
//...
public static void initialize()
{
if (!initialized)
{
threadExecutor = Executors.newScheduledThreadPool(1);
// start the thread that will perform a scheduled check for unsaved player state
threadExecutor.scheduleAtFixedRate(new Runnable() {
#Override public void run() {
// ... the saving operation ...
}
}, 0, 120, TimeUnit.SECONDS);
initialized = true;
}
}
When I'm in debug mode, this thing works both when the app is in the foreground and in the background too, as espected.
Problems come when I switch to RELEASE mode: once the app is in the background (by pressing the home button, for example), this thread stops and the operation is not repeated anymore!
Is there any documentation about this (unexpected?) behavior?
Try using AlarmManager, to run a task every 'x' minutes.
Please refer to this for more information.
And here is an example of an AlarmManager that runs every 2 minutes.
Most of the times we as programmers experience this problem, when we are in between of certain Asynctask doinBackground() Method - performing an operation which requires Network (Internet Connection), and if in between the network is lost then our Application results in Force Close or Crash, or FreeZed. To stop this we use try/catch operations to be used with the code.
I just want to know is there any perfect means to do the same, Scenario written below,
Here in my case:
I require Internet Connection after every 20secs to parse an API in the Asyntask, and based upon the result of the API, I have to update the UI on the screen.
Here is my Timer Method
timer = new Timer();
TimerTask task = new TimerTask() {
#Override
public void run() {
if(DCCStaticMethod.checkInternet(DriverMainMenuActivity.this)){
try {
if(mLocalAreaDriverPass.getStatus() == AsyncTask.Status.FINISHED){
mLocalAreaDriverPass = new LocalAreaDriverPass(DriverMainMenuActivity.this,true);
mLocalAreaDriverPass.execute();
Log.d("RefreshLocalAreaTimerDriver", "running");
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
};
timer.scheduleAtFixedRate(task, 20000, 20000);
Suppose at any instant of time, the internet connectivity is lost or goes down, how to cancel and restart the timer again to achieve my requirement.
I HAVE SO MANY TRICKS AND CRANKS TO PERFORM THE SAME, BUT I AM IN SEARCH OF GOOD MEANS TO PERFORM THESE TYPES OF TASKS IN FUTURE, AS THESE TYPES OF TASKS OCCUR IN ALMOST ALL THE APPS
In Catch block first cancel the Timer and register a broadcast for Network Connection. In broadcast receiver start your timer again.Here are the docs for monitoring Network.
Make broadcast receiver for checking internet connection. and get status of that. if connection is lost then set value to variable of any application class or simple class and then use that variable in activity for stop timer.
There is a custom class CountdownTimerwithPause.By using this you can pause and cancel the timer in middle of Asyn Task
Refer the below link
How to extend CountDown Timer With Pause?
This question already has an answer here:
Spawning threads in a JSF managed bean for scheduled tasks using a timer
(1 answer)
Closed 7 years ago.
I am developing a web application where I need to run a thread for 60 seconds which needs to check for response coming from a webservice. If the response arrives within 60 seconds I will forward to success othewise I will forward to a time out page after 60 seconds. I am using JSF 2.0?
I have thought of using the Timer but not sure whenther I can run the timer for sprcefic amount of time only.
Is there any smart solution for this ??
Yes, youre able to create a timer which expires after a certain amount of time. See this link http://docs.oracle.com/javaee/1.4/api/javax/ejb/TimerService.html.
Java < vers. 6
Create Session- or MessageDriven-Bean
Inject TimerService
#Ressource
TimerService ts;
Create Timer
...
// create Timer which starts after 10s every 10s
Timer timer = ts.createTimer(10000, 10000, "Test-Timer");
...
Important: Timer Interval has to be >7sec, see Java Specs
Create Method to be executed when timer fires
#Timeout //marks Method to be executed by Timer
public void timerFired(Timer timer) {
// your code here
}
Java > vers. 6
Much comfortable with the #Schedule-Annotation
#Schedule(second="*/45", minute="*", hour="*", persistent="false")
public void scheduler() {
// your code here
}
The above code implements a timer which gets fired every 45s of every minute of every hour.
Have a look at wikipedia for more information about cron syntax.
Both methods implement the Serializable-Interface, so they are both thread-safe.
if you would like to extend this rudimental functionality you should take a look at Quartz.
Hope this helped! Have Fun!
Do absolutely not use Timer for this! It's funny for one-time-run desktop applications, but it has severe potential problems when used in a lifetime long running Java EE web application.
Rather use the executors from the java.util.concurrent package. Here's a kickoff example:
ExecutorService executor = Executors.newSingleThreadExecutor(); // An application wide thread pool executor is better.
Callable<InputStream> task = new Callable<InputStream>() {
#Override
public InputStream call() throws Exception {
// Do here your webservice call job.
return new URL("http://stackoverflow.com").openStream();
}
};
try {
InputStream input = executor.invokeAny(Arrays.asList(task), 60, TimeUnit.SECONDS);
// Successful! Forward to success page here.
} catch (TimeoutException e) {
// Timeout occurred. Forward to timeout page here.
}
It sounds like you should just sit in a loop for 60 seconds and sleep for a second between checks. Once 60 seconds has passed or the request came in let the code continue and forward the user to the appropriate page.
This is the simplest way. You could also use an ajax polling system which would be more user friendly because you can update the user interface with a countdown.
long startTime = System.currentTimeMillis();
boolean success = false;
while (System.currentTimeMillis() < startTime + 60000) {
// do check
success = checkSucceeds();
if (success) break;
try {
Thread.sleep(1000);
} catch (InterruptedException interruptedException) {
// ignore
}
}
if (success)
// forward to success page
;
else
// forward to error page
;
i'm currently working on an app for the android os that requires to fetch data from a remote server from time to time.
as this "update" should be carried out even when the actual frontend app is not running, i implemented a remote service that is started on system boot. now i need to schedule a timer to start the update.
is the "Timer"-class the right one for this job? and if "yes": what is the difference between a "normal" Timer() and one started as a "daemon" by Timer(true)?
http://developer.android.com/reference/java/util/Timer.html isn't very helpful with this :(
EDIT:
ok - i see there are much more methods to do this than i expected. to clarify:
i want to execute some code at a time that is specified.
this timer is used to trigger the execution of code 7 days in the future. (i.e., every week at a given weekday and time)
the code should run WITHOUT waking the phone up if it is "sleeping" (screen dimmed).
when running the code, no activity should be started. i.e. no app pops up on the screen.
the code that is executed should fetch some data from the internet. if at this time no internet connection is available, the timer should be set to sth like 30 minutes and then try again.
after completing the code execution, the timer will be set for the next interval which will be 7 days later.
the timer should be started at system boot, e.g., if i reboot the phone, the timer should determine the next date to execute the code and schedule the timer. this has to work without ANY user interaction!
when "sleeping", the thread/service/timer/whatsoever should not consume any system resources if possible...
what i need is pretty much a simple unix cronjob.
i think anyone here knows "newsrob" for android? what i want to realize is pretty much the same as the newsrob-updateservice.
Use AlarmManager. This allows you to set your schedule, then exit your components. Your code does not need to remain in memory and will be triggered when the alarm sounds.
i implemented a remote service that is started on system boot
Please don't do that just for a scheduled task. Use AlarmManager.
If you want the work to be done while the phone is asleep, you will need to use a _WAKEUP alarm type and perhaps use something like my WakefulIntentService to keep the device awake while the work is being done.
I recently had to develop an application following the same pattern.
Here is how I designed it:
I created a service started either explicitely by the frontend when enabling it through a configuration dialog, either started by a BroadcastReceiver waiting for the activation of network connectivity:
<receiver android:name=".notifications.MyReceiver">
<intent-filter>
<action android:name="android.net.conn.BACKGROUND_DATA_SETTING_CHANGED"/>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>
</intent-filter>
</receiver>
The service, when started, starts a new HandlerThread, and associates it with a Looper:
public class MyService extends Service {
private Looper serviceLooper;
private MyHandler serviceHandler;
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
//Toast.makeText(this, "service started", Toast.LENGTH_SHORT).show();
HandlerThread thread = new HandlerThread("MyHandlerThread", Process.THREAD_PRIORITY_BACKGROUND);
thread.start();
serviceLooper = thread.getLooper();
serviceHandler = new MyHandler(this, serviceLooper);
// initial message
serviceHandler.sendMessage(Message.obtain());
}
#Override
public void onDestroy() {
serviceLooper.quit();
//Toast.makeText(this, "service stopped", Toast.LENGTH_SHORT).show();
}
}
When the network goes down or if the frontend disables it, the service is stopped, as well as the looper.
Now, in the MyHandler, I actually get the updates from the server when receiving messages.
public class MyHandler extends Handler {
private final Context context;
public MyHandler(Context context, Looper looper) {
super(looper);
this.context = context;
}
#Override
public void handleMessage(Message msg) {
// handle message and perform update
// ...
// try again 30 minutes
this.sendMessageDelayed(Message.obtain(), 1000 * 60 * 30);
}
}
The trick as you can see, is to send itself a delayed message to be handled 30 minutes later.
The advantage of this solution over using the AlarmManager is that the phone will NOT be forcibly woken up at a designed time, meaning it plays nicer with the phone resources if not needed.
Moreover, I don't start the service at boot time, only when there's an active internet connexion, and I stop it as soon as the connexion is gone.
It's been pretty efficient so far.