What I want is 5 minutes after I open the application do a specific work.
I am not sure what I suppose to do.Should I create an AsyncTask in onCreate method of my main activity or a thread? Or should i do something completely different?
This may help: http://developer.android.com/reference/android/app/AlarmManager.html
Your question is a combined question asking how (way) to perform a task as well as how to schedule it.
Decide what is the task you want to perform. If its a long running task, use either AsyncTask or IntentService
To schedule the task you can either use Hander postDelayed, Timer or AlarmManager. My pref. would be a one-time AlarmManager - Once registered, even if you app is not running, the callback will be triggered.
You could use a Handler :
new Handler().postDelayed(new Runnable() { public void run() {
//your delayed action here, on UI Thread if needed
}
}, 1000 * 60 * 5 );
Regards,
Stéphane
Related
I am working on an application which requires it to go online every x minutes and check for some new data. To prevent heavy network and data usage the task should run at fixed rate, but what is the best approach to use for this kind of solution ? A Handler or a Timer object?
There are some disadvantages of using Timer
It creates only single thread to execute the tasks and if a task
takes too long to run, other tasks suffer.
It does not handle exceptions thrown by tasks and thread just terminates, which affects
other scheduled tasks and they are never run.
Whereas on Other hand, ScheduledThreadPoolExecutor deals properly with all these issues and it does not make sense to use Timer.. There are two methods which could be of use in your case
scheduleAtFixedRate(...)
scheduleWithFixedDelay(..)
class LongRunningTask implements Runnable {
#Override
public void run() {
System.out.println("Hello world");
}
}
ScheduledThreadPoolExecutor exec = new ScheduledThreadPoolExecutor(1);
long period = 100; // the period between successive executions
exec.scheduleAtFixedRate(new LongRunningTask (), 0, duration, TimeUnit.MICROSECONDS);
long delay = 100; //the delay between the termination of one execution and the commencement of the next
exec.scheduleWithFixedDelay(new MyTask(), 0, duration, TimeUnit.MICROSECONDS);
And to Cancel the Executor use this - ScheduledFuture
// schedule long running task in 2 minutes:
ScheduledFuture scheduleFuture = exec.scheduleAtFixedRate(new MyTask(), 0, duration, TimeUnit.MICROSECONDS);
... ...
// At some point in the future, if you want to cancel scheduled task:
scheduleFuture.cancel(true);
You should use a Service and an AlarmReceiver
Like This
That's what they're for. If you use a Timer or any other mechanism in your Activity and you set your data to update every "few minutes" there's a good chance the user will not be in your app and Android may very well clean it up, leaving your app *not updating. The Alarm will stay on till the device is turned off.
if you are looking for a good performance and less battery consume, you should consider an Alarm manager integrated with broadcast Reciever that will call a service in X time and let it do the work then turn it off again.
However, using timer or handler you need to let your service run in background at all times. unless, you want it to get data while the application is running therefore you dont need a service.
if your choice is whether handler or timer, then go with timer because it is more simpler and can do the job in better performance. handlers usually used to update the UI using Runnable or Messeges.
Maybe Alarm Manager, timer, handler or ScheduledThreadPoolExecutor.
Take a look at this:
Scheduling recurring task in Android
It depends on whether updates will occur while the user is not in the app (will the checks halt as soon as the user leaves to send an SMS, for example, or should polling continue?) can the check run on the UI thread then spawn the loading from a service or AsyncTask or other thread? Maybe none of that matters...
If you don't need to update anything while the user is not viewing the app, go with timer. Service would be an overkill. Here is a sample code to achieve this:
final Runnable updateRunnable = new Runnable() {
public void run() {
// Fetch the date here in an async task
}
};
final Handler myHandler = new Handler();
private Timer myTimer;
private void updateUI() {
myHandler.post(updateRunnable);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// ... other things here
myTimer = new Timer();
myTimer.schedule(new TimerTask() {
#Override
public void run() {
updateUI(); // Here you can update the UI as well
}
}, 0, 10000); // 10000 is in miliseconds, this executes every 10 seconds
// ... more other things here
}
Alarm manager or handler. If you use handler and postDelayed, your process doesn't have to stay active all the time.
In fact using Handler is officially recommended over Timer or TimerTask: http://android-developers.blogspot.ru/2007/11/stitch-in-time.html
I want to perform database actions in the background every 10 minutes. What is the best method?
Maybe:
Threads: how?
Services: very complicated?
AsyncTasks: too long period
My current approach:
CountDownTimer clearDBsCountDownTimer = new CountDownTimer(600000, 600000) {
#Override
public void onFinish() {
ClearDBs();
}
};
private void ClearDBs() {
// Clearing databases here
clearDBsCountDownTimer.start();
}
But it's not working: I think because the ClearDBs() method waits for the CountDownTimer to finish, right?
But how to do that correctly: any ideas?
AlarmManager + IntentService is the cleanest approach.
With AlarmManager you can schedule periodic IntentServices.
An IntentService is a service that performs a specific action in a background thread (onHandleIntent() call) and dies.
They make a perfect mix to perform periodic jobs in background.
Check for example this post.
Please be careful with this kind of operations since they could result in draining the battery (and having angry users).
As suggested by #Squonk you can use setRepeating(...) or setInexactRepeating(...) to schedule periodic events.
If you want to perform this background task only when your app is in foreground, you can still cancel the event calling manager.cancel()
Creating a bound service would be a good idea.
And for threading use ScheduledExecutorService
I implemented some app, that waits about some time before action. User can go to preferences and define time to wait. My problem is now that if I press home button I can´t start any other app, because my app take all resources. I have an motorloa milestone and my code is (part of source code of waiting service) :
public void run() {
while(currentTime>waitingTime)
{ currentTime = System.currentTimeMillis();
Thread.sleep(1000);
}
//do Action
}
It is an simple thread, but it seems to be very ineffective. I would be very thanks-full for any help.
you can always use Handler to schedule a Message. But your application needs to be in running state to get a call in Handler's callback mathod(handleMessage(message)). Another option is to go for AlarmManger.
Use AlarmManager to schedule a PendingIntent to be invoked at your designated time.
One of my activity periodically updates nearby friends, which location is obtained from rest service
Currently I use postDelay:
private Runnable updateNearbyFriendsTask = new Runnable() {
#Override
public void run() {
list = api.getNearby(.....)
handler.postDelayed(this, UPDATE_RATE);
}
};
The problem is that postDelayed executed on UI thread, so this runnable task block ui with poor internet connection.
What is the right way to make periodic background rest requests from activity? I don't want to create service for that, because this rest method is used only in this activity.
EDIT
Currently switched to using ScheduledExecutor
this.scheduledExecutor.scheduleWithFixedDelay(new UpdateNearbyFriendsTask(), 0, UPDATE_RATE, TimeUnit.MILLISECONDS);
private class UpdateNearbyFriendsTask implements Runnable() {
#Override
public void run() {
list = api.getNearby(.....)
runOnUiThread(.....)
}
};
I don't see what the problem is with creating a Service, even if it is only used for this activity.
That being said, have a look at the TimerTask. It seems to do what you want.
How about BroadCast receiver using Alarm manager.. http://developer.android.com/reference/android/app/AlarmManager.html
Since its a long running and on going task, would you want to write a Service or an Intent service which does the background job for you.
You can just ping the service whenever your time ticks and let the service do the network activity, freeing up the UI thread for something else. you can always query the service to know the status, or the service itself can respond back to your UI thread.
For ticking the timer, you can use the alarm manager, or perhaps something else (I am not good at any :P )
I'm trying to create a service that runs in a given interval. The service's purpose is to update a database and when done notify an Activity with an Intent.
The service should also be callable from the activity when the user chooses to 'refresh'.
I have accomplished this, but I can't get it to run in a detached thread.
The service executes an update method in a Runnable:
private Runnable refresh = new Runnable() {
public void run() {
update(); //Runs updates
didUpdate(); //Sends broadcast
handler.postDelayed(this, 50000); // 50 seconds, calls itself in 50 secs
}
};
I have another runnable called ManualRefresh that is called via a broadcast from the activity.
However these runnables seem to be blocking the UI.
Need advice! :)
When you run a Runnable by calling it's run method, it runs on the current thread. To run on a background thread, you need to use new Thread(refresh).start(); (if the Runnable you want run is refresh).
You can also make use of AsyncTask for this, but that's more appropriate for an activity than for a Service. Information about using AsyncTask can be found in the API docs and in the article Painless Threading.
I suggest to write the service using the AlarmManager. The service will receive an Intent to tell it to periodically to update the database.
Once updated, you can notify the Activity with an Intent (as you mentioned).
When the user wants to manually refresh, have the Application sent an Intent to you service. Receiving the Intent from the AlarmManager or from the Activity would perform the same code.
You may also want to reschedule the alarm after a request to manually refresh.