I am in a google map project and here is my code in oncreate:
mapView = (MapView)findViewById(R.id.mapView);
mapView.setBuiltInZoomControls(true);
mapView.setSatellite(false);
mapView.setStreetView(true);
mapController = mapView.getController();
mapController.setZoom(19);
getLastLocation();
drawCurrPositionOverlay();
drawMalls();
animateToCurrentLocation();
but now i want to call this DrawMalls(); method after some seconds and unless the user closes this application this method will be being called after that time? Is there any way to do this?
You can use Handler and Runnable combination to execute statements after a period of time.
You can delay a Runnable using postDelayed() method of Handler.
Runnable mRunnable;
Handler mHandler=new Handler();
mRunnable=new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
drawMalls();
//If you want to re call this method at a gap of x seconds then you can schedule handler again
mHandler.postDelayed(mRunnable,2*1000);
}
};
mHandler.postDelayed(mRunnable,10*1000);//Execute after 10 Seconds
If you want to cancel this then you have to use removeCallback() method of Handler like mHandler.removeCallbacks(mRunnable);
Or You can use Timer. You can refer an example here http://thedevelopersinfo.wordpress.com/2009/10/18/scheduling-a-timer-task-to-run-repeatedly/
You can follow the instructions for using a ScheduledExecutorService here I've had bugs before where timer's wouldn't be stopped and started properly on 2.1, the scheduling scheme described worked perfectly for me though.
There are two ways
1) using Handler
2)Using Timer
//using Timer//
public void OnCreate(Bundle SaveInstanceState())
{
------------
-----------------
PreferedTime pTime=new preferedTime();
Timer t=new Timer(false);
t.Schedule(pTime,2000);
}
class PreferedTime extends TimerTask
{
public void run()
{
drawMalls();
}
}
//method 2//
public void OnCreate(Bundle SaveInstanceState())
{
-----------------
-----------------
Handler handler=new handler(new Runnable()
{
public void run()
{
drawMalls();
}
},2000);
You could use a java.util.Timer's schedule() method to arrange future execution of drawMalls():
Timer t = new Timer();
t.schedule(
new TimerTask()
{
public void run()
{
System.out.println("hello\n");
}
},
2000); // Milliseconds: 2 * 1000
I am unsure if drawMalls() is a static or non-static method. If it is static then it is straightforward to call in the TimerTask.run() method. Otherwise, you will need to arrange for the class instance to which drawMalls() belongs is available to the run() method of TimerTask:
class DrawMallsTask extends TimerTask
{
public DrawMallsTask(YourClass a_build) { _instance = a_instance; }
public void run() { _instance.DrawMalls(); }
private YourClass _instance;
};
Timer t = new Timer();
t.schedule(new DrawMallsTask(this), 2000);
EDIT:
To repeatedly run the task after every two seconds you can use:
t.scheduleAtFixedRate(new DrawMallsTask(this), 2000, 2000);
MyCount counter;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
counter= new MyCount(60000,1000);
counter.start();
}
public class MyCount extends CountDownTimer{
public MyCount(long millisInFuture, long countDownInterval) {
super(millisInFuture, countDownInterval);
}
#Override
public void onFinish() {
counter= new MyCount(60000,1000);
}
#Override
public void onTick(long millisUntilFinished) {
s1=millisUntilFinished/1000;
if(s1%2==0)
{
drawMalls();
}
}
}
this one calls drawMalls() for every 2 seconds..u can change it as required..
If re-executing code is not bound to state of application, but only to time period, look at Timer class
http://developer.android.com/reference/java/util/Timer.html
Timer timer;
function myCallerFunction(){
timer = new Timer();
timer.schedule(seconds * 1000); //must be in milliseconds
}
private class MyTask extends TimerTask {
public void run() {
drawMalls();
}
}
Related
I need a thread to start after 3 seconds of a button being idle, is there a simple way of doing it?
I'm building a counter app, the button triggers two counters, the total counter and the "tapping counter", the tapping counter helps keep track of the actual change of values, showing how many taps the user did, I need it to vanish after some seconds so the user can tap again.
for stuffs like that I usually use a Handler with a Runnable in order to do stuff after X milliseconds the user isn't doing a specific action.
First, create a runnable and a handler
final android.os.Handler handler = new android.os.Handler();
private Runnable runnable;
private final long DELAY = 3000; // how many milliseconds you want to wait
Then add the onClickListener:
myButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
}
});
Then, inside onClick event, remove callbacks and istantiate the handler again as follows:
if(runnable != null) {
// in this case the user already clicked once at least
handler.removeCallbacks(runnable);
}
runnable = new Runnable() {
#Override
public void run() {
//this code will run when user isn't clicking for the time you set before.
}
};
handler.postDelayed(runnable, DELAY);
Final result:
final android.os.Handler handler = new android.os.Handler();
private Runnable runnable;
private final long DELAY = 3000; // how many milliseconds you want to wait
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// all your previous stuffs
myButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if(runnable != null) {
// in this case the user already clicked once at least
handler.removeCallbacks(runnable);
}
runnable = new Runnable() {
#Override
public void run() {
//this code will run when user isn't clicking for the time you set before.
}
};
handler.postDelayed(runnable, DELAY);
}
});
}
I hope this helps, for any question feel free to ask
Handler may work in this scenario, with a 3000 milisecond delay.
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
// do action
}
}, 3000);
At first, you create a Timer with a TimerTask(with your Thread) and schedule it to run after 3 seconds.
Every time the button is pressed, you reset the timer.
public class MyClass{
private Timer timer=new Timer()
private TimerTask task=new TimerTask(){
public void run(){
//your action
}
};
public void init(){
timer.schedule(task,3000);
}
public void onButtonClick(){
task.cancel();
timer.schedule(task,3000);
}
}
I've got game based on CountDownTimer, which is continuously repeating countdowns. This countDown is counting time for user to react on some action related to number, if user reacts onFinish() is called by some clickListener or by itself if the time was up. Depending of succesCondition(), method success or fail is called and those methods are defining if game is still running.
OnCreate
loop = gameLoop(time).start();
MainActivity
public CountDownTimer gameLoop(int time){
return new CountDownTimer(time, time+100) {
#Override
public void onTick(long millisUntilFinished) {
}
#Override
public void onFinish() {
if (!Conditions.succesCondition(number)) {
success();
} else {
fail();
}
}
};
}
public void success() {
loop.cancel();
scoreCount++;
animation.start();
}
public void fail(){
loop.cancel();
}
However this timer runs on Main thread and that provides well known issue skipped xx frames, your app might be doing too much work on its main thread and I found that this is common issue for CountDownTimer and replacing it with Handler is a solution.
I can't put this timer in AsyncTask because it performs mainly UI related tasks (TextViews, TextSwitcher, some progressBar etc. in success() method. I didn't put that in code in those methods for more clean view of the main problem. I'm trying to reconstruct CountDownTimer- like concept with handler and runnable to replace my Timer, but I'm actually stuck with nothing. As you can see I'm using only onFinish method, onTick is not necessary.
I suggest using a combination of java.util.Timer, java.util.TimerTask and Activity.runOnUiThread(). First create a Timer and call one of its schedule...()methods. Any action that needs to be done on the main (ui) thread can be wrapped in runOnUiThread(() -> { ...}). Be sure to call cancel() on TimerTask and Timer if those objects are no longer needed. Cancelling the Timer cancels the TimerTask as well.
Here is how this may look like:
public class TimerTaskActivity extends Activity {
Timer timer;
TimerTask timerTask;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.timertask);
...
}
#Override
protected void onStart() {
super.onStart();
timer = new Timer();
timerTask = new TimerTask() {
#Override
public void run() {
runOnUiThread(() -> {
....
});
}
};
timer.scheduleAtFixedRate(timerTask, 2000, 2000);
}
#Override
protected void onPause() {
super.onPause();
timer.cancel();
}
}
You may handle this situation using AsyncTask as well overriding the onProgressUpdate method.
Here's an example about how you can achieve the behaviour to interact with your main thread from AsyncTask. The example shows the update of a download which can be easily transformed to your specific problem of timer.
Update
In my case almost all code would be in onProgressUpdate, would it
still make any sense?
No, your code will not be in onProgressUpdate. The onProgressUpdate method will only be updating your timer in your UI. As far as I could understand, the success and the fail will be triggered based on user action as well. Then those actions are triggered, you can stop the AsyncTask to update your timer as well. You just need to AsyncTask to update the timer value time to time.
You will get a callback in your Activity when the AsyncTask finishes. See the mNotificationHelper.completed(); function in the above example. When you are notified in your Activity when the timer finishes, you might then execute the following task there.
public void completed() {
if (!Conditions.succesCondition(number)) {
success();
} else {
fail();
}
}
OK. I finally figured out how to handle it with handler (hehe):
public void startGameAction() {
//My game actions
handler = new Handler();
runnable = () -> {
if (!Conditions.succesCondition(number)) {
success();
} else {
fail();
}
};
handler.postDelayed(runnable,time);
}
public void success(){
handler.removeCallbacks(runnable);
handler = null;
scoreCount++;
//other stuff
startGameAction();
}
private void fail() {
handler.removeCallbacks(runnable);
//other stuff
}
onCreate only startGame call, handler and runnable defined as class fields
startGameAction();
I am trying to load some data. Id data is loaded in 20 seconds than i start new activity else i will finish by giving some relevant message. I have started a countdownTimer to keep track of time. Once data is loaded, I want to stop the timer. I have Following class :
public class SplashActivity extends AppCompatActivity {
private Context mContext;
private Boolean mDataLoadedFromServer = false;
private String mJSONData;
private SplashTimerForLoadingMasterDataForAllChannels mTimer;
private void stopTimer(){
mTimer.cancel();
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mContext = this;
setContentView(R.layout.activity_splash);
mTimer = new SplashTimerForLoadingMasterDataForAllChannels(20000,1000);
mTimer.start();
}
class SplashTimerForLoadingMasterDataForAllChannels extends CountDownTimer {
public SplashTimerForLoadingMasterDataForAllChannels(long millisInFuture, long countDownInterval) {
super(millisInFuture, countDownInterval);
Log.d("testTimer", "SplashTimerForLoadingMasterDataForAllChannels");
//SomE AsyncTAsk
LoadData loaddata = new LoadData();
loaddata.execute();
//SomE AsyncTAsk
}
#Override
public void onTick(long millisUntilFinished) {
Log.d("testTimer", "onTick millisUntilFinished = " + millisUntilFinished + " mDataLoadedFromServer = " + mDataLoadedFromServer);
//mDataLoadedFromServer is modified once Data is loaded in AsyncTask
if(mDataLoadedFromServer) {
stopTimer();
}
}
#Override
public void onFinish() {
Log.d("testTimer", "onFinish");
if(mDataLoadedFromServer) {
mDataSavedAndNextActivityLaunched = true;
if (Utils.checkIfUserLoggedIn()) {
mContext.startActivity(new Intent(mContext, ABCACtivity.class));
} else {
mContext.startActivity(new Intent(mContext, XYZActivity.class));
}
finish();
}
}
}
}
I cancel it in a local method call but onTick still keeps getting called. Can someone please help?
Basically counter does not simply stop if I cancle it from onTick() or from onFinish() ie FROM INSIDE TIMER.
However it stops very easily if I do it from any point outside of timer.
So the point at which my data is fully loaded...I called timer.cancle() and it did the trick.
However I still dont understand why it does not work if we do same from inside timer methods.
I tried this code snippet, since most answers are saying you cannot cancel the timer inside its implementation, thus i tried using a handler inside onFinish. Old post but if anyone comes across this its helpful.
new Handler().post(new Runnable() {
#Override
public void run() {
timerTextView.setText("00:" + String.format("%02d", counter));
cancel();
}
});
you need to call stopTimer() outside of the CountDownTimer's onTick(),
something like this
#Override
public void onFinish() {
Log.d("testTimer", "onFinish");
if(mDataLoadedFromServer) {
mDataSavedAndNextActivityLaunched = true;
if (Utils.checkIfUserLoggedIn()) {
mContext.startActivity(new Intent(mContext, ABCACtivity.class));
} else {
mContext.startActivity(new Intent(mContext, XYZActivity.class));
}
finish();
stopTimer();
}
}
I want to repeatedly call a method after every 5-seconds and whenever I wish to to stop the repeated call of the method I may stop or restart the repeated call of the method.
Here is some sample code that whats really I want to implement. Please help me in this respect I would be very thankful to you.
private int m_interval = 5000; // 5 seconds by default, can be changed later
private Handler m_handler;
#Override
protected void onCreate(Bundle bundle)
{
...
m_handler = new Handler();
}
Runnable m_statusChecker = new Runnable()
{
#Override
public void run() {
updateStatus(); //this function can change value of m_interval.
m_handler.postDelayed(m_statusChecker, m_interval);
}
};
public void startRepeatingTask()
{
m_statusChecker.run();
}
public void stopRepeatingTask()
{
m_handler.removeCallbacks(m_statusChecker);
}
Set repeated task using this:
//Declare the timer
Timer t = new Timer();
//Set the schedule function and rate
t.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
//Called each time when 1000 milliseconds (1 second) (the period parameter)
}
},
//Set how long before to start calling the TimerTask (in milliseconds)
0,
//Set the amount of time between each execution (in milliseconds)
1000);
and if you wanted to cancel the task simply call t.cancel() here t is your Timer object
and you can also check comment placed below your answer they have given brief information about that.
Use a Handler in the onCreate() method. Its postDelayed() method causes the Runnable to be added to the message queue and to be run after the specified amount of time elapses (that is 0 in given example). Then this will queue itself after fixed rate of time (1000 milliseconds in this example).
Refer this code :
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
android.os.Handler customHandler = new android.os.Handler();
customHandler.postDelayed(updateTimerThread, 0);
}
private Runnable updateTimerThread = new Runnable()
{
public void run()
{
//write here whaterver you want to repeat
customHandler.postDelayed(this, 1000);
}
};
use TimerTask to call after specific time interval
Timer timer = new Timer();
timer.schedule(new UpdateTimeTask(),1, TimeInterval);
and
class UpdateTimeTask extends TimerTask {
public void run()
{
// do stufff
}
}
Do it in Android's way with the help of Handler.
Declare a Handler which does not leak Memory
/**
* Instances of static inner classes do not hold an implicit
* reference to their outer class.
*/
private static class NonLeakyHandler extends Handler {
private final WeakReference<FlashActivity> mActivity;
public NonLeakyHandler(FlashActivity activity) {
mActivity = new WeakReference<FlashActivity>(activity);
}
#Override
public void handleMessage(Message msg) {
FlashActivity activity = mActivity.get();
if (activity != null) {
// ...
}
}
}
Declare a runnable which handle your task
private Runnable repeatativeTaskRunnable = new Runnable() {
public void run() {
new Handler(getMainLooper()).post(new Runnable() {
#Override
public void run() {
//DO YOUR THINGS
}
};
Initialize handler object in your Activity/Fragment
//Task Handler
private Handler taskHandler = new NonLeakyHandler(FlashActivity.this);
Repeat task after fix time interval
taskHandler.postDelayed(repeatativeTaskRunnable , DELAY_MILLIS);
Stop repetition
taskHandler .removeCallbacks(repeatativeTaskRunnable );
You have to put this code inside the activity you want to call every 5 seconds
final Runnable tarea = new Runnable() { public void run() {
hola_mundo();//the operation that you want to perform }};
ScheduledExecutorService timer = Executors.newSingleThreadScheduledExecutor();
timer.scheduleAtFixedRate(tarea, 5, 5, TimeUnit.SECONDS);
Ok - I know there has got to be a simple solution to this but for the life of me I can't figure it out.
Programming a very basic android activity to simply iterate through 0-99. I have a textview that I want to display the count. What happens is that it simply stays blank until the end and then shows the ending count (99).
Not sure if a textview is the right way to display or what the answer is. Any help is greatly appreciated. Thanks in advance
Try using code like this in onCreate (where number is defined as a field):
textView.post(new Runnable() {
#Override
public void run() {
number++;
textView.setText("counting: " + number);
if (number < 100) {
textView.postDelayed(this, 50);
}
}
});
Edit: code was edited as View classes have post and postDelayed, which propagates call to Handler instance they have internally.
You need to read a bit about Handler class.
Warning: this code leaks Activity for the time of approximatelly 5 seconds and should not be used directly in production code. You need to remove Runnable from the message queue at the appropriate time (maybe in onDestroy, but it depends on your needs).
View.removeCallbacks for anti-memory-leak.
My guess is that your onCreate() has code like this:
for (int i=0;i<100;i++) {
tv.setText(String.valueOf(i));
Thread.sleep(100); // or something to delay for a bit
}
That will give you the output that you are describing.
As with many GUI frameworks, Android's UI is event-driven. Calling setText() does not update the screen. Rather, it puts a message on a queue, asking for the screen to be updated. That queue is processed by the main application thread... the same thread that is calling onCreate() in the first place. Hence, what you are doing is queuing up 100 setText() calls, none of which will be processed until your loop is complete. Applying the 100 of them takes very little time, giving the visual result of only seeing the last change.
User a timer scheduled at a fixed rate. Increment a counter every second. Set the text on the UI thread. cancel the timer when required.
public class MainActivity extends Activity {
TextView _tv;
Timer _t;
int _count=0;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
_tv = (TextView) findViewById( R.id.textView1 );
_t = new Timer();
_tv.setText(""+_count);
_t.scheduleAtFixedRate( new TimerTask() {
#Override
public void run() {
_count++;
runOnUiThread(new Runnable() //run on ui thread
{
public void run()
{
_tv.setText(""+_count);
if(_count==99)
{
_t.cancel();
}
}
});
}
}, 1000, 1000 );
}
#Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
_t.cancel();
}
}
Use a countdown timer, in below code, onTick() will get called every second, here you can display/update your number each second.
set interval according to your need. Its in mili seconds.
public class TimerActivity extends Activity {
private final long startTime = 100 * 1000;
private final long interval = 1 * 1000;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_timer);
countDownTimer = new MyCountDownTimer(startTime, interval);
countDownTimer.start();
public class MyCountDownTimer extends CountDownTimer {
public MyCountDownTimer(long startTime, long interval) {
super(startTime, interval);
}
#Override
public void onFinish() {
text.setText("Time's up!");
}
#Override
public void onTick(long millisUntilFinished) {
text.setText(100 - millisUntilFinished/1000);
}
}
}