I am using Eclipse for Android. I am trying to make a simple repeating Timer that has a short delay.
It will start after a TextView timerTV is clicked. This code is in the onCreate method:
timerTV = (TextView) findViewById(R.id.timerTV);
timerTV.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Timer gameTimer = new Timer();
TimerTask doThis;
int delay = 5000; // delay for 5 sec.
int period = 1000; // repeat every sec.
doThis = new TimerTask() {
public void run() {
Toast.makeText(getApplicationContext(), "timer is running", Toast.LENGTH_SHORT).show();
}
};
gameTimer.scheduleAtFixedRate(doThis, delay, period);
Everytime I try to run it, a "Class File Editor" pops up with the error:
"Source not found"
The JAR file C:\Program Files\Android\android-sdk\platforms\android-8\android.jar has no source attachment.
You can attach the source by clicking Attach Source below:
[Attach Source...]
When I click this, Eclipse asks me to select the location folder containing 'android.jar'
I tried to do this, but cannot navigate all the way to the folder it is located in anyway.
I presume the issue is in my code somewhere.
I have been searching for hours, even copied and pasted code many times.
Using an actual Timer (java.util.Timer) in conjunction with runOnUiThread() is one way to solve this issue, and below is an example of how to implement it.
public class myActivity extends Activity {
private Timer myTimer;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.main);
myTimer = new Timer();
myTimer.schedule(new TimerTask() {
#Override
public void run() {
TimerMethod();
}
}, 0, 1000);
}
private void TimerMethod()
{
//This method is called directly by the timer
//and runs in the same thread as the timer.
//We call the method that will work with the UI
//through the runOnUiThread method.
this.runOnUiThread(Timer_Tick);
}
private Runnable Timer_Tick = new Runnable() {
public void run() {
//This method runs in the same thread as the UI.
//Do something to the UI thread here
}
};
}
SOURCE: http://steve.odyfamily.com/?p=12
Try using Project -> Clean then right click your project and find Fix Project Properties. Check your Build Path. It could be any one of these things. Restart eclipse, make sure your Android Manifest is targeting the correct API, 8 I assume?
Related
Is there any function in Android that can use to make the activity wait for an interval and continue working?
I mean , for example, I use setContentView() to set a layout , and after 3 seconds it will load another layout, and continue to do another job, I don't need to repeat doing same thing after an interval, just continue do another thing.
Thanks in advanced.
You can Use Following Method to Set Interval
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
// This method will be executed once the timer is over
// Do your code here
}
}, 3000);
Here, 1000 = 1 Second
But Before running this code make sure that you are not in BACKGROUND PROCESS THREAD...otherwise this may cause an error..
Do it at Android Style:
Handler mHandler = new Handler();
mHandler.postDelayed(runnableHandler, 3000);
private Runnable runnableHandler = new Runnable() {
#Override
public void run() {
doSomething()
}
};
private void doSomething() {
// Before do something remove all callbacks from Handler
mHandler.removeCallbacks(runnableHandler);
andFinallyDoWhatYouNeed();
}
What I want to do is just a basic implementation of handler example. I have a TextView on the mainActivity, and once the page loads the handler is supposed to run and show the user value coming from SystemClock.uptimeMillis. But ıt doesn't work more than once. How can I make this code run?
public class MainActivity extends Activity {
long uptoMS=0L;
TextView tv;
Handler handler=new Handler();
long swaptime=0L;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv=(TextView)findViewById(R.id.textView1);
uptoMS=SystemClock.uptimeMillis();
tv.setText(String.valueOf(uptoMS));
handler.post(runner);
}
private Runnable runner=new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
swaptime+=uptoMS;
tv.setTag(String.valueOf(swaptime));
handler.post(this);
}
};
}
See this below example
scheduler(){
TimerTask tasknew = new TimerSchedulePeriod();
Timer timer = new Timer();
// scheduling the task at interval
timer.schedule(tasknew,100, 100);
}
// this method performs the task
public void run() {
System.out.println("timer working");
}
timer = new Timer();
refreshTask = new TimerTask() {
#Override
public void run() {
swaptime+=uptoMS;
tv.setTag(String.valueOf(swaptime));
handler.post(this);
}
};
timer.schedule(refreshTask,
100, 100);
Well, there some problems with your code.
Firstly, you use setTag() instead of setText(), so the value will never update.
tv.setTag(String.valueOf(swaptime));
Secondly, you get uptoMS once in onCreate(), and then you use it in every "handler loop". I don't know what you try to achive but it's unlike that you want this.
Thirdly, you instantly repost your Runnable, so the main thread's message queue will be busy. You should give some break instead of instant reposting. For example you can wait 100 ms between the updates, so the TextView will be updated 10 times in every second.
handler.postDelayed(this, 100);
And finally, however others suggest you using Timer, just ignore them. Handler is the Android way to achieve tasks like this.
In my android app, I have the following relevant piece of code:
/*Code outside*/
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Timer t = new Timer();
t.scheduleAtFixedRate(
new TimerTask(){
public void run(){
stuffToBeDone();
}
},someVariableDelay,someVariablePeriod);
}
}
Everything was going fine until I noticed that stuffToBeDone() was running once for every time I pressed the button. As far as I understand, every time onClick() is called and the old Timer should not exist anymore, but somehow the TimerTask survives.
In the second button click, I no longer have a reference to the first Timer to cancel() it (because it should not exist anymore). And if I declare the Timer as a final variable in the Code outside so that I can do it, after canceling I cannot reuse it anymore. So how can I terminate that TimerTask but then still be able to use a Timer?
Android Timer is thread based from the Android Developers website:
http://developer.android.com/reference/java/util/Timer.html
When a timer is no longer needed, users should call cancel(), which releases the timer's thread and other resources. Timers not explicitly cancelled may hold resources indefinitely.
I would recommend instantiating the timer inside the onclicklistener only i.e. something similar to this:
/*Code outside*/
Timer t = null;
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
if(t == null)
t = new Timer();
else
t.cancel();
t.scheduleAtFixedRate(
new TimerTask(){
public void run(){
stuffToBeDone();
}
},someVariableDelay,someVariablePeriod);
}
}
I have a TextView. I want to update its text (append a "1") after 1 second of a button click.
public class HaikuDisplay extends Activity {
Method m;
Timer t;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
t = new Timer();
m = HaikuDisplay.class.getMethod("change");
}
//Event handler of the button
public void onRefresh(View view)
{
//To have the reference of this inside the TimerTask
final HaikuDisplay hd = this;
TimerTask task1 = new TimerTask(){
public void run(){
/*
* I tried to update the text here but since this is not the UI thread, it does not allow to do so.
*/
//Calls change() method
m.invoke(hd, (Object[])null);
}
};
t.schedule(task1, 1000);
}
public void change()
{
//Appends a "1" to the TextView
TextView t = (TextView)findViewById(R.id.textView1);
t.setText(t.getText() + "1");
}
//Event handler of another button which updates the text directly by appending "2".
//This works fine unless I click the first button.
public void onRefresh1(View view)
{
TextView t = (TextView)findViewById(R.id.textView1);
t.setText(t.getText() + "2");
}
}
Consider all Exceptions be handled.
On first click, m.invoke gives InvocationTargetException. But it calls the method change() on successive invokes without any Exceptions(verified by logging). But it does not update the text. Where am I wrong?
Also, I see in the debugger that it creates a new Thread every time I click the button. That is fine. But why isn't it removing the previous Threads though their execution has been completed?
Do something like this
public void onRefresh1(View v) {
// You can have this in a field not to find it every time
final EditText t = (EditText) findViewById(R.id.textView1);
t.postDelayed(new Runnable() {
#Override
public void run() {
t.append("1");
}
}, 1000);
}
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
// Update UI
}
}, 1000);
implement this on button click
UPDATE:
There are some other answers. dtmilano suggested another solution which is almost same to mine except he is calling the postDelayed method of View class and In my answer I used postDelayed method of handler class.
from the api reference of android the postDelayed method of Handler says
The runnable will be run on the thread to which this handler is
attached.
and the postDelayed method of View says
The runnable will be run on the user interface thread.
This is the only difference between these two solution. in my answer instead of creating new Handler every time you can use any other handler instance. Then the runnable will be run on that thread where that specific handler is declared. And if the postDelayed of EditText is used the the runnable method will be run on the user Interface Thread.
Now the performance issue, both has the same performance (If anybody can prove me wrong with reference I will be happy)
That's looking awful convoluted - have you considered using CountDownTimer instead?
new CountDownTimer(1000, 1000) {
public void onTick(long millisUntilFinished) {
// no-op
}
public void onFinish() {
change();
}
}.start();
This should call change (and hence change the text) on the UI thread, avoiding reflection and threading errors.
Hi Use the following code for that. Hope this will help you .
new java.util.Timer().schedule(
new java.util.TimerTask() {
#Override
public void run() {
// your code here
}
},
1000
);
Have a look of this question also.
display data after every 10 seconds in Android
You can try with this also.
private Handler handler = new Handler();
private Runnable runnable = new Runnable() {
public void run() {
doStuff();
/*
* Now register it for running next time
*/
handler.postDelayed(this, 1000);
}
};
**EDIT 3**
Try with this once you are need to enable once (i mean if you put your code in yourmethod()== this will get automatically call 1 seconds once.
private Timer timer;
TimerTask refresher;
// Initialization code in onCreate or similar:
timer = new Timer();
refresher = new TimerTask() {
public void run() {
yourmethod();
};
};
// first event immediately, following after 1 seconds each
timer.scheduleAtFixedRate(refresher, 0,100);
I'm extending the CountDownTimer class to obtain some custom functionality .In onTick() in case some conditions are met I call cancel() , expecting that will be the end of it, however the onTick() callback gets call until the the count down is reached . So how to prevent this from happening ?
CountDownTimer.cancel() method seems to be not working. Here's another thread without a solution Timer does not stop in android.
I would recommend you to use Timer instead. It's much more flexible and can be cancelled at any time. It may be something like that:
public class MainActivity extends Activity {
TextView mTextField;
long elapsed;
final static long INTERVAL=1000;
final static long TIMEOUT=5000;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mTextField=(TextView)findViewById(R.id.textview1);
TimerTask task=new TimerTask(){
#Override
public void run() {
elapsed+=INTERVAL;
if(elapsed>=TIMEOUT){
this.cancel();
displayText("finished");
return;
}
//if(some other conditions)
// this.cancel();
displayText("seconds elapsed: " + elapsed / 1000);
}
};
Timer timer = new Timer();
timer.scheduleAtFixedRate(task, INTERVAL, INTERVAL);
}
private void displayText(final String text){
this.runOnUiThread(new Runnable(){
#Override
public void run() {
mTextField.setText(text);
}});
}
}
CountDownTimer is also working fine for me, but I think it only works if you call it OUTSIDE of the CountDownTimer implemetation (that is don't call it in the onTick).
Calling it inside also didn't worked.
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();
}
});