Timer in android java - java

I have 2 activity in activity2 i have a timer when activity create timer is started in activity on_Destroy i put timer_task.cancel(); but When opened the activity2 for the second time is create new timer task and not Canceled or destroyed the last timer and 2 timer is while be run in one activity
my code
private TimerTask mTimerTask;
private void doTimerTask(){
nCounter = 4;
qtimer.setMax(20);
if(mTimerTask!=null) {
mTimerTask.cancel();
}
mTimerTask = new TimerTask() {
public void run() {
handler.post(new Runnable() {
public void run() {
Log.d("Timerrrr",nCounter+"");
if(nCounter<1){
Finished();
}else {
qtimer.setProgress(nCounter);
nCounter--;
}
}
});
}};
// public void schedule (TimerTask task, long delay, long period)
t.schedule(mTimerTask, 0, 1000); //
}
private void stopTask() {
if (mTimerTask != null) {
Log.d("nCounter canceled",nCounter+"");
mTimerTask.cancel();
}
}
#Override
protected void onDestroy() {
super.onDestroy();
mTimerTask.cancel();
MainActivity.this.finish();
}

Try This...
public void stopTimerTask(View v) {
//stop the timer, if it's not already null
if (mTimerTask != null) {
mTimerTask.cancel();
mTimerTask = null;
}
}
And Where do u call your stopTask() method?
And I suggest don't put mTimerTask.cancel(); in onDestroy(), but put it in onStop().
I hope this helps you.

Related

How To Destroy CoundownTimer in Java when the button is pressed?

I make a timer with a count time of 5 seconds, then when I press the exit button the counter automatically stops?
Here is my timer code:
public void startTimer(final long finish, long tick) {
CountDownTimer t;
t = new CountDownTimer(finish, tick) {
public void onTick(long millisUntilFinished) {
long remainedSecs = millisUntilFinished / 1000;
textTimer.setText("" + (remainedSecs / 60) + ":" + (remainedSecs % 60));// manage it accordign to you
}
public void onFinish() {
textTimer.setText("00:00");
Toast.makeText(FloatingVideoWidgetShowService.this, "Waktu Habis", Toast.LENGTH_SHORT).show();
long seek = videoView.getCurrentPosition();
videoView.setKeepScreenOn(false);
stopSelf();
WritableMap args = new Arguments().createMap();
args.putInt("index", index);
args.putInt("seek", (int) seek);
args.putString("url", playingVideo.getString("url"));
args.putString("type", "close");
sendEvent(reactContext, "onClose", args);
onDestroy();
cancel();
}
}.start();
}
And this is my code when pressing the stop / exit button :
floatingWindow.findViewById(R.id.btn_deny).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
long seek = videoView.getCurrentPosition();
videoView.setKeepScreenOn(false);
stopSelf();
WritableMap args = new Arguments().createMap();
args.putInt("index", index);
args.putInt("seek", (int) seek);
args.putString("url", playingVideo.getString("url"));
args.putString("type", "close");
sendEvent(reactContext, "onClose", args);
onDestroy();
}
});
How so when btn_deny is clicked Cuntdowntimer stops and does not force close?
Thanks.
You can't use onDestroy() to close your activity or fragment. Instead, you need to call finish().
To close the CountDownTimer, you need to make it a class scope variable. Prepare the timer at your startTimer then stop the timer by calling t.cancel() like the following code:
public class YourActivity extends Activity {
// Declare the variable to be accessed later.
CountDownTimer t;
...
public void startTimer(final long finish, long tick) {
t = new CountDownTimer(finish, tick) {
...
}.start();
}
private void yourOtherMethod() {
floatingWindow.findViewById(R.id.btn_deny).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if(t != null) t.cancel();
...
}
});
}
}

I am trying to display a CountDownTimer on screen and I get "Only one looper can be created per thread" in my logcat

I'm a beginner in Android programming. I'm trying to display a timer for an upgrade in my game to show how long the upgrade will be activated for. In my collision flag I call Looper.prepare and start my thread class as the logcat suggested I do. How would I get this to run on one looper?
Here is the snippet that starts the thread.
BigGapUpgrade.java
public boolean playerCollectUpgrade(Player player){
if(Rect.intersects(rectangle, player.getRectangle())){
Looper.prepare();
bigGapUpgradeHandler.start();
}
return Rect.intersects(rectangle, player.getRectangle());
}
And here is my thread class
BigGapUpgradeHandler.java
public class BigGapUpgradeHandler extends Thread {
TimerTask scanTask;
Timer timer = new Timer();
#Override
public void run() {
Looper.prepare();
scanTask = new TimerTask() {
public void run() {
}
};
timer.schedule(scanTask, 0, 4000);
CountDownTimer countDownTimer = new CountDownTimer(4000, 100) {
#Override
public void onTick(long l) {
Log.i(TAG, "onTick: ");
}
#Override
public void onFinish() {
timer.cancel();
Log.i(TAG, "onFinish: ");
}
}.start();
Looper.loop();
}
}
After running it I get this error
W/System.err: java.lang.RuntimeException: Only one Looper may be created per thread
--Edit
Here is the solution I came up with.
-- Solution
new Handler(Looper.getMainLooper()).post(new Runnable() {
#Override
public void run() {
CountDownTimer countDownTimer = new CountDownTimer(5000,100) {
#Override
public void onTick(long millisUntilFinished) {
millis = millisUntilFinished/100;
}
#Override
public void onFinish() {
}
}.start();
}
});
OK, So what you can do is just use a TimerTask. That creates it's own background thread for you do stuff:
// This TimerTask Updates the UI so it needs a reference to the Activity.
static class PowerUpTimerTask extends TimerTask
{
WeakReference<AppCompatActivity> mActivity;
long mInterval;
long mPeriod;
public PowerUpTimerTask(AppCompatActivity activity, long period, long interval)
{
mActivity = new WeakReference<>(activity);
mInterval = interval;
mPeriod = period;
}
#Override
public void run()
{
AppCompatActivity activity = mActivity.get();
if (activity != null)
{
final TextView timerTextView = activity.findViewById(R.id.timerTextView);
mPeriod -= mInterval;
if (mPeriod > 0)
{
// Set time remaining
activity.runOnUiThread(new Runnable()
{
#Override
public void run()
{
timerTextView.setText(String.valueOf(mPeriod));
}
});
}
else
{
// Out of time...clear the Text and stop the timer task.
activity.runOnUiThread(new Runnable()
{
#Override
public void run()
{
timerTextView.setText("");
}
});
Log.d(TAG, "Timer done. Canceling.");
cancel();
}
}
else
{
// Cancel this timer task since we don't have a reference to
// the Activity any more.
Log.d(TAG, "Lost reference to Activity. Canceling.");
cancel();
}
}
}
Then you can start your Timer task like so:
...
// Will count down from 10 by 1s.
mPowerUpTimerTask = new PowerUpTimerTask(this, powerUpTime, 1);
// Schedule for every second.
Timer t = new Timer();
t.scheduleAtFixedRate(mPowerUpTimerTask, 1000, 1000);
...
Here is a link to this running sample:
https://github.com/didiergarcia/TimerTaskExample
I think you have to use LocalBroadcastManager for the timing to continuously in loop. Please check below code for for that :-
private void startTimer() {
countDownTimer = new CountDownTimer(Constant.getInstance().ANSWER_TIME_IN_SECOND * 1000, 1000) {
public void onTick(long millisUntilFinished) {
remaininTimeInMillies = millisUntilFinished;
tvTimer.setText(getTime(Integer.parseInt(String.valueOf(millisUntilFinished))));
}
public void onFinish() {
Intent intent = new Intent(Constant.getInstance().TIMER_RECEIVER);
LocalBroadcastManager.getInstance(PatientDetailActivity.this).sendBroadcast(intent);
}
};
countDownTimer.start();
}
private String getTime(int milliSec) {
int minut = 0, second = 0;
minut = milliSec / 60000;
second = (milliSec - (minut * 60000)) / 1000;
String strMinute = "", strSecond = "";
if (minut < 10) {
strMinute = "0" + String.valueOf(minut);
} else {
strMinute = String.valueOf(minut);
}
if (second < 10) {
strSecond = "0" + String.valueOf(second);
} else {
strSecond = String.valueOf(second);
}
return strMinute + ":" + strSecond;
}
#Override
protected void onResume() {
LocalBroadcastManager.getInstance(this).registerReceiver(timerBroadcast, new IntentFilter(Constant.getInstance().TIMER_RECEIVER));
super.onResume();
}
#Override
protected void onDestroy() {
LocalBroadcastManager.getInstance(this).unregisterReceiver(timerBroadcast);
super.onDestroy();
}
Thanks and Hope that will help you

Timer.schedule runs once even with period

I'm a student trying to create an app for my miniproject for one of my modules and I'm trying to create an app that grabs data from a server every few seconds so it's updated. I tried using java timer and timerTask to run the code repeatedly but the program only run once and the get-button doesn't work as intended (suppose to grab data instantly) after implementing the timer. Android Emulator
public class MainActivity extends AppCompatActivity implements OnClickListener{
private Button speed;
private TextView result;
Timer timer;
TimerTask timerTask;
private TextView sSpeed;
final StringBuilder builder = new StringBuilder();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
result = (TextView) findViewById(R.id.result);
sSpeed = (TextView) findViewById(R.id.sSpeed);
speed = (Button) findViewById(R.id.get_button);
speed.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View view) {
getWebsite();
}
});
View aboutButton = this.findViewById(R.id.about_button);
aboutButton.setOnClickListener(this);
View exitButton = this.findViewById(R.id.exit_button);
exitButton.setOnClickListener(this);
}
public void onClick(View v) {
switch (v.getId()){
case R.id.get_button:
getWebsite();
break;
case R.id.about_button:
Intent i = new Intent(this, About.class);
startActivity(i);
break;
case R.id.exit_button:
finish();
break;
}
}
private void getWebsite(){
new Thread(new Runnable() {
#Override
public void run() {
try{
Document doc = Jsoup.connect("http://10.0.2.2:8080/Start_Stop_buttons_UTF8.html").get();
// Elements element = doc.getElementsByTag("p");
Elements element = doc.select("p");
//String title = doc.title();
builder.append(title).append("\n");
for (Element tag : element){
builder.append("\n\n").append(tag.text());
}
}catch(IOException e){
//e.printStackTrace();
builder.append("Error : ").append(e.getMessage()).append("\n");
}
runOnUiThread(new Runnable() {
#Override
public void run() {
String a = builder.toString(); // parse data from html into new string
a = a.substring(a.indexOf(":")+1, a.indexOf("Control")).trim();//trim string content
String b = builder.toString();
b = b.substring(11,b.indexOf(":")+1).trim();
double speed = Double.parseDouble(a);//convert string into double
if (speed<1000)
Log.i("HTML text","too slow");
else if((speed> 1500))Log.i("HTML text","too fast!");
result.setText(a);
sSpeed.setText(b);
}
});
}
}).start();
}
protected void onResume() {
super.onResume();
startTimer();
}
public void startTimer(){
timer = new Timer();
timerTask = new TimerTask() {
#Override
public void run() {
getWebsite();
}
};
timer.schedule(timerTask,1500,3000);
}
public void stopTimer(){
if(timer != null){
timer.cancel();
timer.purge();
}
}
}
Am I implementing the timer correctly to run getwebsite() repeatedly and able to get an instant update when get-button is clicked like it should have? Or is there a better way to implement these features using different method?
You are never calling the startTimer method in your ClickListener. You make one call to getWebsite. Change your call to startTimer.
speed.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View view) {
startTimer();
}
});
You also might want to check if the timer is already running before you start a new one. To do that assign a null value on your stopTimer method e.g.
public void stopTimer(){
if(timer != null){
timer.cancel();
timer.purge();
timer = null;
}
}
And your startTimer would look like this
public void startTimer(){
if(timer != null) return; // don't start multiple timers
timer = new Timer();
timerTask = new TimerTask() {
#Override
public void run() {
getWebsite();
}
};
timer.schedule(timerTask,1500,3000);
}

A thread start on a button click and ending the thread with another button click

Sir Please help me to add a thread that starts on a button click and ends the thread with another button click. In between I have a sound playing till the thread stops.
You can try this simple code:
final volatile boolean toExit = false;
final Thread t = new Thread(new Runnable() {
#Override
public void run() {
while(!toExit){
// Your code
Thread.sleep(100);
}
}
});
findViewById(R.id.button1).setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
t.start();
}
});
findViewById(R.id.button2).setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
toExit = true;
}
});
The thread will stop after button2 clicked and run to while(!toExit).
Threads stop method is deprecated.
The best solution will be having a boolean variable in the run method.
Your Thread:
public class MyThread implements Runnable {
private static final Logger LOGGER = LoggerFactory.getLogger(IndexProcessor.class);
private volatile boolean running = true;
public void terminate() {
running = false;
}
#Override
public void run() {
while (running) {
try {
//Your code that needs to be run multiple times
LOGGER.debug("Processing");
} catch (InterruptedException e) {
LOGGER.error("Exception", e);
running = false;
}
}
}
}
In your Activity:
MyThread t=new Thread();
findViewById(R.id.button1).setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
t.start();
}
});
findViewById(R.id.button2).setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
t.terminate();
}
});
Use Below Code
public class SomeBackgroundProcess implements Runnable {
Thread backgroundThread;
public void start() {
if( backgroundThread == null ) {
backgroundThread = new Thread( this );
backgroundThread.start();
}
}
public void stop() {
if( backgroundThread != null ) {
backgroundThread.interrupt();
}
}
public void run() {
try {
Log.i("Thread starting.");
while( !backgroundThread.interrupted() ) {
doSomething();
}
Log.i("Thread stopping.");
} catch( InterruptedException ex ) {
// important you respond to the InterruptedException and stop processing
// when its thrown! Notice this is outside the while loop.
Log.i("Thread shutting down as it was requested to stop.");
} finally {
backgroundThread = null;
}
}
Hope this will help you

Stop and start timer

Sorry for my english. I have timer and i wand if i click timer is on if i click again timer off. But my timer on only one time. If i click again(off timer) i have exception like this:
E/AndroidRuntime﹕ FATAL EXCEPTION: main
java.lang.IllegalStateException: Timer was canceled
at java.util.Timer.scheduleImpl(Timer.java:561)
at java.util.Timer.schedule(Timer.java:481)
at installation.ConnectDevice.callAsynchronousTask(ConnectDevice.java:211)
at installation.ConnectDevice$1.onClick(ConnectDevice.java:153)
at android.view.View.performClick(View.java:4240)
...
I dont know why its not work, please help. Below my class
My class
private Timer timer;
int time = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.i_connect_device);
timer = new Timer();
// my botton
includeDevice.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (time < 1) {
callAsynchronousTask();
time++;
}
if (time > 0) {
stopTimer();
time--;
}
}
});
}
public void callAsynchronousTask() {
final Handler handler = new Handler();
TimerTask doAsynchronousTask = new TimerTask() {
#Override
public void run() {
handler.post(new Runnable() {
public void run() {
try {
Log.e("Timer is work", "Timer is work");
// GetMsgs performBackgroundTask = new GetMsgs();
// PerformBackgroundTask this class is the class
// that extends AsynchTask
// performBackgroundTask.execute();
} catch (Exception e) {
// TODO Auto-generated catch block
}
}
});
}
};
timer.schedule(doAsynchronousTask, 0, 1000 * 10); // execute in every
// 50000 ms
}
public void stopTimer() {
timer.cancel();
}
Change onClick logic as follows (because in your case at the first time only executed callAsynchronousTask() and stopTimer(). so it raises exception at next onClick)
btnTimer.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (time == 0) {
callAsynchronousTask();
time = 1;
} else {
stopTimer();
time = 0;
}
}
});
and doAsynchronousTask make it as field and cancel task on stopTimer().
public void stopTimer() {
doAsynchronousTask.cancel();
}
then it works fine.
From Javadocs:
cancel() : Terminates this timer, discarding any currently scheduled tasks. [...] Once a timer has been terminated, its execution thread terminates gracefully, and no more tasks may be scheduled on it.
and
schedule(Task task, long delay)
throws:
IllegalStateException - if task was already scheduled or cancelled, timer was cancelled, or timer thread terminated.
So basically, your class tells you that it cannot complete the set task due to the fact that the timer has been cancelled. Something you could try is to make the timer sleep until the button is pressed again, instead of cancelling it completely.
Once you cancel the timer; you cannot start it again because thread is stopped.See the link:Pause the timer and then continue itYou have to maintain the state somehow and recreate timer with the current value
You need an async task it is a class so you can extend it. Public class callAsynchronousTask extends async task
And GetMsgs performBackgroundTask = new GetMsgs();
// PerformBackgroundTask this class is the class that extends Async Taskbar goes into the do in background method
Initialize your timer object inside callAsynchronousTask as shown below.
public void callAsynchronousTask() {
final Handler handler = new Handler();
TimerTask doAsynchronousTask = new TimerTask() {
#Override
public void run() {
handler.post(new Runnable() {
public void run() {
try {
Log.e("Timer is work", "Timer is work");
//GetMsgs performBackgroundTask = new GetMsgs();
// PerformBackgroundTask this class is the class that extends AsynchTask
//performBackgroundTask.execute();
} catch (Exception e) {
// TODO Auto-generated catch block
}
}
});
}
};
timer=new Timer();
timer.schedule(doAsynchronousTask, 0, 1000*10); //execute in every 50000 ms
}
Also modify your in block because it is executing both if condition .
Use boolean flag instead of int
boolean isTimerRunning;
if (!isTimerRunning) {
callAsynchronousTask();
isTimerRunning=true;
}
else (isTimerRunning) {
stopTimer();
isTimerRunning=false;
}

Categories