CountDownTimer in EditText lag in the last second - android

I would like to set an EditText with a timer thanks to CountDownTimer.
My EditText write second by second the number 3 and 2 but for the 1 there is a lag (it take 1,5 to 2 seconds).
Maybe I do it wrong.
This is my code :
CountDownTimer mCountDownTimer = new CountDownTimer(4000, 1000) {
#Override
public void onTick(long millisUntilFinished) {
txt_timer.setText(String.valueOf(millisUntilFinished / 1000));
}
#Override
public void onFinish() {
txt_timer.setText("GO");
}
};
mCountDownTimer.start();

That is because the UI thread is doing too much work. Try running a new thread on the UI thread itself:
runOnUiThread(new Runnable() {
public void run()
{
//Insert your code
}
});
}
Let me know if you can;t get this to work!

The memory in the device cause the problem. I found a solution running a new thread.
I have to declare int i=4; before and use this code :
new Thread() {
public void run() {
while (i-- > 1) {
try {
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
txt_timer.setText(String.valueOf(i));
}
});
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
txt_timer.setText("GO");
}
}.start();

Related

switching an image widget in timeline

I want to create an android widget with switching image with time delay. I have no idea about how to do this. Should I create Thread in methood onUpdate?
this example of my layout.xml file:
<ImageButton
android:id="#+id/imageViewWGT"
android:background="#drawable/dog" />
and this is what I want to known how to do correct:
public class MainActivity extends AppWidgetProvider {
private int counter = 0;
private ImageView wgt_img;
wgt_img = wgt_img.findViewById(R.id.imageViewWGT);
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
new Thread(new Runnable() {
#Override
public void run() {
while (true) {
runOnUiThread(new Runnable() {
#Override
public void run() {
if (counter%2 == 0){
wgt_img.setImageResource(R.drawable.dog);
}else
wgt_img.setImageResource(R.drawable.cat);
}
});
counter++;
try {
Thread.sleep(1000); // sleep 1 sec
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
}
}
You can use postDelayed method of Handler class like
// Initialisation
Handler handler = new Handler();
int counter = 0;
long switchDelay = 1000L;
// Function for switch images
public void switchImage(){
handler.postDelayed(new Runnable() {
#Override
public void run() {
if (counter%2 == 0){
wgt_img.setImageResource(R.drawable.dog);
}else {
wgt_img.setImageResource(R.drawable.cat);
}
counter++;
// Recall method
switchImage();
}
}, 1000);
}
when you need to run a block of code in schedule at time you can use Timer.
look at this sample code :
new Timer().scheduleAtFixedRate(new TimerTask()
{
#Override
public void run()
{
//you'r code
}
} , DELAY , PERIOD);
add you'r code in run method and replace your delay and period of execute time instead of DELAY and PERIOD .
DELAY and PERIOD are millisecond
also if you want run your block code one time with delay you can use Handler.
new Handler().postDelayed(new Runnable()
{
#Override
public void run()
{
//you'r code
}
} , DEALY_MILLIS);
The android has a default methood to update widget in timeline
<appwidget-provider
...
...
...
...
android:updatePeriodMillis="1000000">
</appwidget-provider>
But it works if you update the widget at least 30 minutes

Running backgound thread every X seconds (Android Studio)

I have a code that plays 5 sounds with 1 second delay between the sounds and I want this part of code to be executed every 5 seconds (so it will run in a row so far as a boolean variable is true, and when it becomes false the tread run stopped - I have a button to both start and stop this executions). Everything works perfectly, but the issue is that I can't get rid of the 5 seconds delay in the first time I click the button, so when I first click, the sounds beggins only after 5 seconds. How can I make it start right away and only after the first time start taking the delays?
Here is the button onClick code:
public void clickHandlerStartTempo(final View view) {
if (!tempoOn) {
Toast toast = Toast.makeText(getApplicationContext(), "Start Tempo!", Toast
.LENGTH_SHORT);
toast.show();
tempoOn = true;
final Handler handler = new Handler();
final int delay = 5000; //milliseconds
handler.postDelayed(new Runnable() {
public void run() {
if (tempoOn) {
runCode(view);
handler.postDelayed(this, delay);
}
}
}, delay);
} else {
Toast toast = Toast.makeText(getApplicationContext(), "Stop Tempo!", Toast
.LENGTH_SHORT);
toast.show();
tempoOn = false;
}
}
And here is the runCode method:
public void runCode(View view) {
Runnable runnable = new Runnable() {
#Override
public void run() {
playSound(0);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
for (int i = 0; i < 4; i++) {
if (tempoOn) {
playSound(1);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
return;
}
}
}
};
Thread thread = new Thread(runnable);
Log.i(TAG, "runCode: Thread id = " + thread.getId());
thread.start();
}
I'm new to android development and any help would be very much appreciated.
Thanks.
First you need to playsound without thread after that you will execute your reaming 5 second logic stop thread after 4 count.
public void onStartPress(){
playSound();
someMethod();
}
public void someMethod(){
Handler uiHandler = new Handler(Looper.getMainLooper());
uiHandler.postDelayed(new Runnable() {
#Override
public void run() {
playSound();
someMethod();
}
},1000);
}
Don't use actual Threads unless you really want to do something off the Ui thread. Most of the time you do want to keep things on the Ui thread.
For simple repeating tasks, you can easily repurpose the CountDownTimer class. Often with an (almost) infinite run time or Long.MAX_VALUE (292 million years). The fist onTick happens immediately after starting.
private CountDownTimer mTimer;
private void start() {
if (mTimer == null) {
mTimer = new CountDownTimer(Long.MAX_VALUE, 5000) {
#Override
public void onTick(long millisUntilFinished) {
// start a beeping countdown
new CountDownTimer(5000, 1000) {
private int state = 1;
#Override
public void onTick(long millisUntilFinished) {
playSound(state);
state = state + 1 % 2;
}
#Override
public void onFinish() {
playSound(0);
}
}.start();
}
#Override
public void onFinish() { /* ignore, never happens */ }
};
mTimer.start();
}
}
private void stop() {
if (mTimer != null) {
mTimer.cancel();
mTimer = null;
}
}

Android- Updating UI elements with threading

I have a textview which i want to change with a thread and do it again and again (Like a digital clock). But i'm having problems with setting time between 2 changes. Here, the code:
display1 = (TextView) findViewById(R.id.textView1);
Thread timer2 = new Thread(){
#Override
public void run() {
synchronized (this){
runOnUiThread(new Runnable() {
#Override
public void run() {
int i = 0;
display1.setText("" + i);
try {
sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
display1.setText("" + (i+1));
}
});
}
}
};
timer2.start();
This sleep(2000); function makes textview invisible for the given time but i want it stand still till the next change. How can i do that?
But i'm having problems with setting time between 2 changes
Do NOT do sleep() on your UI thread. If you want to chain some actions with the delay, split your code into two runnables and the first one should set display1 and then post second runnable with the delay using postDelayed()
EDIT
want one of them to increase 3 per sec, and the other 5 per sec until they reach 1000 for instance
You can make your Runnable post itself until some criteria are met (i.e. time, counter value etc). Just at the end your Runnable check your conditions and if not met, call postDelayed(this, delay); and you are good.
You should use a Handler instead and dispatch your changes to the UI thread.
Handler mHandler = new Handler();
mHandler.post(new Runnable() {
#Override
public void run() {
// Code to be run right away
}
});
mHandler.postDelayed(new Runnable() {
#Override
public void run() {
// Code to be run after 2 seconds
}
}, 2000);
Maybe split up what you need to do into separate methods. Here you have a UI method and a sleep method split up. Hope it helps
private void myMethod() {
new Thread() {
#Override
public void run() {
int i = 0;
doWorkOnUI(String.valueOf(i));
pause(2000);
doWorkOnUI(String.valueOf(i++));
}
}.start();
}
private void pause(int pauseTime) {
try {
Thread.sleep(pauseTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private void doWorkOnUI(final String string) {
runOnUiThread(new Runnable() {
#Override
public void run() {
display1.setText(string);
}
});
}

Updating UI using a Handler freezes my app

I am trying to make a clock, using a TextView :)
Someone here told me that I couldn't use normal threads to change the UI, but Handler or AsyncTask. I managed to get it working a few days ago, but was not a consistent thread.
Now what I want is a consistent thread that is always changing the text of my Textview. I tried using this, but didn't work, any help?
private void startClock() {
new Handler().postDelayed(new Runnable(){
#Override
public void run() {
while (true) {
final long millis = System.currentTimeMillis() - MainActivity.startedAt;
clock.setText("" + millis);
runOnUiThread (new Runnable() {
#Override
public void run() {
clock.setText("" + millis);
}
});
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}, 2000);
}
you should get rid of:
while(true) {
....
sleep(1000);
...
}
because this get your thread stuck forever. your program should work like this:
private Handler mHandler = new Handler();
#Override
public void onResume() {
super.onResume();
mHandler.removeCallbacks(mUpdateClockTask);
mHandler.postDelayed(mUpdateCLockTask, 100);
}
#Override
public void onPause() {
super.onPause();
mHandler.removeCallbacks(mUpdateClockTask);
}
private Runnable mUpdateClockTask = new Runnable() {
public void run() {
updateClock();
mHandler.postDelayed(mUpdateClockTask, 2000);
}
};
and inside updateClock() you do all your UI updates.
Look here for an example https://stackoverflow.com/a/11140429/808940
Also note that you have a duplicate line in your code:
clock.setText(""+millis);
It appears both in the runOnUiThread and in the main handler, it should only appear in the runOnUiThread runnable

Countdown Timer which shows on the UI with AsyncTask

I'm trying to implement a Countdown Timer which shows on the UI,
I thought this was a clean and elegant solution but Logcat throws
AndroidRuntime(3282): java.lang.RuntimeException: An error occured while executing doInBackground()
,
private class UpdateCountdownTask extends AsyncTask<Long, Long, Void> {
#Override
protected Void doInBackground(Long... millisUntilFinished) {
new CountDownTimer(millisUntilFinished[0], 1000) {
#Override
public void onTick(long millisUntilFinished) {
publishProgress(millisUntilFinished);
}
#Override
public void onFinish() {
((TextView) findViewById(R.id.answer)).setText(answer);
}
};
return null;
}
#Override
protected void onProgressUpdate(Long... millisUntilFinished) {
super.onProgressUpdate(millisUntilFinished);
((TextView) findViewById(R.id.timer)).setText(""
+ millisUntilFinished[0] / 1000);
}
}
Still don't fully understand threads. Can anyone tell me what I'm doing wrong?
Thanks.
UPDATE: Very Sorry. I am an absolut incompetent. I had forgotten to call the metod start() on the counter. :P
I finally went for implementing the countdown with the CountDownTimer by itself. Sill don't know if this actually runs on a separate thread or not but it works now.
CountDownTimer myCounter = new CountDownTimer(millisUntilFinished, 1000) {
#Override
public void onTick(long millisUntilFinished) {
((TextView) findViewById(R.id.timer)).setText(""
+ millisUntilFinished / 1000);
System.out.println("I am ticking");
}
#Override
public void onFinish() {
}
};
myCounter.start();
I think the problem is the onFinish() method inside CountDownTimer. Here you're modifiying the UI thread, and you cannot do this from a background thread. So you have to put ((TextView) findViewById(R.id.answer)).setText(answer); inside onPostExecute() method. I mean:
protected void onPostExecute(String result) {
super.onPostExecute(result);
((TextView) findViewById(R.id.answer)).setText(answer);
}
I hope this works.
You will not be able to connect the UI when doing somthing in background.In my opinion what you want is possible if you use a thread.This will make your work much more easier.A small piece of code is shown below.I hope this may help you.I am trying to set an image instead you can settext.Here i had done using a thread and a handler.Its impossible to connect the UI inside the thread.In assynctask When you are doing something in background you are compleatly inside the thread.Thats why you are getting a error here.Otherwinse you can do it in Postexecute()
Thread animator = new Thread() {
public void run() {
int i = 0;
try {
sleep(2000);
while (i < 4) {
sleep(50);
handler.sendMessage(handler.obtainMessage(i));
i++;
}
} catch (Exception e) {
}
}
};
animator.start();
handler = new Handler() {
#Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if (msg.what == 0) {
animatedimage.setImageResource(R.drawable.sub1);
} else if (msg.what == 1) {
animatedimage.setImageResource(R.drawable.sub2);
} else if (msg.what == 2) {
animatedimage.setImageResource(R.drawable.sub3);
} else if (msg.what == 3) {
animatedimage.setImageResource(R.drawable.sub4);
}
}
};
Have you consider using Handler to update UI every second?
checkout http://developer.android.com/resources/articles/timed-ui-updates.html

Categories

Resources