All I am looking to do is run some function 5 seconds after the app starts. However i keep getting a "force close" after 5 sec. Is timerTask even the correct function to be using in a situation like this? How about if i want to press a button later in the program, and have an event occur 5 seconds after user presses the button?
package com.timertest;
import java.util.Timer;
import java.util.TimerTask;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
public class timerTest extends Activity {
Timer timer = new Timer();
TextView test;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
test = (TextView)findViewById(R.id.test);
timer.schedule(task, 5000);
}
TimerTask task = new TimerTask() {
#Override
public void run() {
test.setText("task function run");
}
};
}
A TimerTask will run on a background thread but you're trying to change UI. You want to run your operation on the UI thread instead. Android traditionally uses messages posted to a Handler to do this. A Handler will not create a new thread, when used as shown below it will simply attach to the same message queue that your app uses to process other incoming UI events.
public class Test extends Activity {
private final Handler mHandler = new Handler();
private TextView mTest;
private Runnable mTask = new Runnable() {
public void run() {
mTest.setText("task function run");
}
};
/** Called when the activity is first created. */
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mTest = (TextView) findViewById(R.id.test);
mHandler.postDelayed(mTask, 5000);
}
#Override
protected void onDestroy() {
super.onDestroy();
mHandler.removeCallbacks(mTask);
}
}
If you want to execute some code after 5 secs try the following...
new CountDownTimer(5000,5000)
{
#Override
public void onTick(long millisUntilFinished) {
}
#Override
public void onFinish() {
// DO YOUR OPERATION
}
}.start();
Related
I have an asynchronous task that i will like to repeat every 10 secs allowing focus to move back to the user interface in my Android application.
I have tried using java.util.Timer & TimerTask but the app crashes. It works within a for loop as you can see but i need to have this repeated every 10 secs.
do ...while loop also doesn't work even if i include a Thread.Sleep(10000), delay.
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.*;
import android.os.AsyncTask;
public class MainActivity extends AppCompatActivity {
TextView statusDisplay,display;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
display=(TextView)findViewById(R.id.display);
display.setText("display");
statusDisplay=(TextView)findViewById(R.id.statusDisplay);
statusDisplay.setText("status");
//I need to make this call every 10 secs
new MyAsyncTask().execute("start");//Works fine as a single execution
}
//Our AsynTask
// Specify your own types <params,progress,result>
private class MyAsyncTask extends AsyncTask<String,Integer,Integer>
{
String status="Task being setup";
int counter=0;
//Step 1 that is executed for setting up our Asynchronous task
#Override
protected void onPreExecute()
{
super.onPreExecute();
display.setText(status);
statusDisplay.setText(String.valueOf(counter));
}
//Step 2 runs in the background and is only executed once
//So put whatever computations including access to the Network inside this method
//Do not make any calls to the UI from inside this method as its running in the background
#Override
protected Integer doInBackground(String[] params)
{
try{
status=params[0];
for(int i = 0;i<10;i++){
counter++;
status = "Task Running" + " " + String.valueOf(counter) + " " + "of" + " " + "10";
publishProgress(counter);//Calls onProgressUpdate
Thread.sleep(1000);
}
}
catch(InterruptedException ex){
}
status = "Task completed";
return counter;
}
//Step 3 called when we make a call to publishProgress in doInBackground
#Override
protected void onProgressUpdate(Integer[] values)
{
super.onProgressUpdate(values);
display.setText(String.valueOf(values[0]));
statusDisplay.setText(status);
}
//Step 4 Called after completion of doInBackground. Its return value is passed on to this method
//Make final update changes to your UI at this step
#Override
protected void onPostExecute(Integer result)
{
super.onPostExecute(result);
display.setText(String.valueOf(result));
statusDisplay.setText(status);
}
}
}
You could use ScheduledExecutorService:
private ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
Runnable yourTaskRunner = new Runnable() {
public void run() { new MyAsyncTask().execute("start"); }
}
scheduler.scheduleAtFixedRate(yourTaskRunner, 0, 10, TimeUnits.SECONDS);
Which is one of the four ways described here.
This is what ive tried but not seeing the delay. It only reruns periodically
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.*;
import android.os.AsyncTask;
import android.os.Handler;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class MainActivity extends AppCompatActivity {
TextView statusDisplay,display;
int x=0;
Handler handler = new Handler();
int stopcondition=0;
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
display=(TextView)findViewById(R.id.display);
display.setText("display");
statusDisplay=(TextView)findViewById(R.id.statusDisplay);
statusDisplay.setText("status");
//new MonitorSecurityStatus().execute("start");//This works fine
//handler.post(rerunCode);//A)Runs periodically and terminates when stop-condition occurs but we don't see the 5 sec delay
//handler.postDelayed(rerunCode,5000);//B) Executes rerunCode after 5 sec delay we don't need this
scheduler.scheduleWithFixedDelay(rerunCode,0,5000, TimeUnit.MILLISECONDS);//C) Behaves same as A)
}
private Runnable rerunCode = new Runnable() {
#Override
public void run()
{
//handler.postDelayed(this,5000);//A) We dont see the 5 secs delay behaves same as if this declaration was inside else-if
stopcondition++;
if(stopcondition==10){
handler.removeCallbacks(this);
}
else if(stopcondition<10)
{
new MonitorSecurityStatus().execute("start");
handler.postDelayed(this,5000);//A) We dont see the 5 secs delay
}
}
};
I making an app and I would run in to a problem that I can't fix.
I am using Android Studio and I need to make a Button that I have already made. Do more then it already does. I want it to after display a text also close the app. Do you know how I should program that. It would be very helpful. Thanks in advance.
Here is the Java code:
package test.myapplication;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void buttonOnClick(View v) {
Button button=(Button) v;
((Button) v).setText("Correct");
}
public void buttonAnClick(View q) {
Button button=(Button) q;
((Button) q).setText("Niet goed");
}
}
So I have already made the button in XML and told it:
android:onClick="buttonOnClick"
Hope you can help me out!
If you're looking to have something happen afterwards what you're looking for is this:
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
//What you want to happen later
}
}, 1500); //1500 = 1.5 seconds, time in milli before it happens.
Put that in your button's method.
If you want to close your app you should call
finish();
Finish closes out the current activity. If you have other activities on the stack you'd return to them but since you likely only have 1 it should take you out.
Try this.
public void buttonOnClick(View v) {
Button button=(Button) v;
((Button) v).setText("Correct");
new android.os.Handler().postDelayed(new Runnable() {
#Override
public void run() {
finish();
}
},1000); // milliseconds: 1 seg.
}
Check out CountDownTimer
CountDownTimer(30000, 1000) {
public void onTick(long millisUntilFinished) {
mTextField.setText("seconds remaining: " + millisUntilFinished / 1000);
}
public void onFinish() {
mTextField.setText("done!");
}
}.start();
If you are trying to get something done with a delay when a button is pressed then do it something like this:
public void buttonOnClick(View v) {
Button button=(Button) v;
button.setText("Correct");
button.postDelayed(new Runnable(){
public void run() {
//runs after 1 second delay on UI thread
}
}, 1000L);
}
If you want to pause then use java.util.concurrent.TimeUnit.
For example:
TimeUnit.SECONDS.sleep(1);
Just put method into your button click function
public void buttonOnClick(View v) {
//call method here
}
If you want to use RxJava
Disposable di = Observable.timer(2, TimeUnit.SECONDS)
.subscribe(timer->{
//next action after 2 seconds
},throwable->{
// throw exception
});
To destroy disposable use, di.dispose();
if Use Runnable and Handler
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
//next action after 2 seconds
}
}, 2*1000);
to stop the handler use, handler.removeCallbacksAndMessages(null);
As the title suggests I am trying to create a Stopwatch app and am having problems adding a lap button and continue button that work. I have added the buttons to the layout.xml file but am having trouble with the java code that gets them to function.
I need to display the "stopped/paused" time when the lap button is clicked, the internal clock needs to keep running however and no longer be displayed, or the stopped/paused time needs to be shown in a new display whichever is easier to accomplish. When the lap timer is clicked subsequently it should display the current time (internal clock)
I need the continue button to then resume the paused/stopped time.
Could somebody help me with the code, I'm relatively inexperienced in java, so any help would be appreciated
here's the code of my main java file:
package com.hfad.stopwatch;
import android.os.Bundle;
import android.os.Handler;
import android.app.Activity;
import android.os.SystemClock;
import android.view.View;
import android.widget.Button;
import android.widget.Chronometer;
import android.widget.TextView;
public class StopwatchActivity extends Activity implements View.OnClickListener {
Button Continue;
Button lapChrono;
Chronometer chrono;
long time =0;
//Number of seconds displayed on the stopwatch.
private int seconds = 0;
//Is the stopwatch running?
private boolean running;
private boolean wasRunning;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_stopwatch);
Continue=(Button)findViewById(R.id.Continue_button);
lapChrono=(Button)findViewById(R.id.lap_button);
lapChrono.setOnClickListener(this);
Continue.setOnClickListener(this);
chrono=(Chronometer)findViewById(R.id.chronometer);
if (savedInstanceState != null) {
seconds = savedInstanceState.getInt("seconds");
running = savedInstanceState.getBoolean("running");
wasRunning = savedInstanceState.getBoolean("wasRunning");
}
runTimer();
}
#Override
protected void onPause() {
super.onPause();
wasRunning = running;
running = false;
}
#Override
protected void onResume() {
super.onResume();
if (wasRunning) {
running = true;
}
}
public void onClick(View arg0) {
switch (arg0.getId()){
case R.id.Continue_button:
chrono.setBase(SystemClock.elapsedRealtime()+time);
chrono.setBase(time);
break;
case R.id.lap_button:
time = chrono.getBase()+SystemClock.elapsedRealtime();
break;
}
}
#Override
public void onSaveInstanceState(Bundle savedInstanceState) {
savedInstanceState.putInt("seconds", seconds);
savedInstanceState.putBoolean("running", running);
savedInstanceState.putBoolean("wasRunning", wasRunning);
}
//Start the stopwatch running when the Start button is clicked.
public void onClickStart(View view) {
running = true;
}
//Stop the stopwatch running when the Stop button is clicked.
public void onClickStop(View view) {
running = false;
}
//Reset the stopwatch when the Reset button is clicked.
public void onClickReset(View view) {
running = false;
seconds = 0;
}
//Sets the number of seconds on the timer.
private void runTimer() {
final TextView timeView = (TextView)findViewById(R.id.time_view);
final Handler handler = new Handler();
handler.post(new Runnable() {
#Override
public void run() {
int hours = seconds/3600;
int minutes = (seconds%3600)/60;
int secs = seconds%60;
String time = String.format("%d:%02d:%02d",
hours, minutes, secs);
timeView.setText(time);
if (running) {
seconds++;
}
handler.postDelayed(this, 1000);
}
});
}
}
I am just having problems getting things to run smoothly as I'm not too fluent in my Java, apologies, that is why help is needed. The logic isn't quite there. The continue button doesn't function properly nor does the lap, I'm needing it to function as described above.
chrono object is not initialized and used in onClick(). Hence NPE occurs.
Try to initialise it in onCreate().
I have a very simple test application I'm making, and to set the seekBar's position I'm using a runnable. Although I have very little experience with actually working with a runnable.
public class MySpotify extends Activity implements Runnable {
private SeekBar progress;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.spotify_app);
myProgress = (SeekBar) findViewById(R.id.myBar);
}
#Override
public void run() {
myProgress.setProgress(25);
}
}
If I move myProgress.setProgress(25); into the onCreate then it works. But I want it to be set off in the runnable. Any ideas?
You need to post() a Runnable to a Thread for it to execute. Try calling post(this); inside onCreate().
Try
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.spotify_app);
myProgress = (SeekBar) findViewById(R.id.myBar);
myProgress.post(new Runnable()
{
public void run()
{
myProgress.setProgress(25);
}
});
}
You need something to run the post() method on
You can start the run method by just calling run();
Be aware that it will execute on the main thread.
Also be aware that it will run only once since there is no loop.
if you want to update while doing something else you sjould create a new thread.
example:
public class MySpotify extends Activity{
private SeekBar myProgress; //I asume it is call "myProgress" instead of "progress"
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.spotify_app);
myProgress = (SeekBar) findViewById(R.id.myBar);
ThreadExample example = new ThreadExample();
example.start();
/* Start a new thread that executes the code in the thread by creating a new thread.
* If ou call example.run() it will execute on the mainthread so don't do that.
*/
}
private class ThreadExample extends Thread{
public void run() {
myProgress.setProgress(25);
}
}
}
I want to make a background application in countdowntimer, that is if i am starting
the timer and comes out of that application, and going to another application then
coming back to that same countdowntimer application. i want that timer to be
running until i stop. I know about the methods involved in it, but i am not sure
about the threading concepts used in it.
//MyActivity.class
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class MyappActivity extends Activity
{
private static final String Tag = "Background_Timer";
private Button start;
private Button stop;
private TextView tv;
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
start = (Button) findViewById(R.id.button);
stop = (Button) findViewById(R.id.button1);
tv = (TextView) findViewById(R.id.text1);
this.runOnUiThread(new Runnable()
{
public void run()
{
tv.setText(MyAppService.seconds + " Seconds Left");
}
});
}
public void onClick(View src)
{
switch (src.getId())
{
case R.id.button:
Log.e(Tag, "onClick: starting service");
startService(new Intent(this, MyAppService.class));
break;
case R.id.button1:
Log.e(Tag, "onClick: stopping service");
stopService(new Intent(this, MyAppService.class));
break;
}
}
}
//MyService.class
import android.app.Service;
import android.content.Intent;
import android.os.CountDownTimer;
import android.os.IBinder;
import android.util.Log;
import android.widget.TextView;
public class MyAppService extends Service
{
private static final String TAG = "My Service";
private static boolean state;
private static TextView TextTimer;
public static String seconds;
MyThread mt = new MyThread();
#Override
public void onCreate()
{
CountDownTimer Myapp = new CountDownTimer(50000, 1000)
{
public void onTick(long millisUntilFinished)
{
TextTimer.setText("Seconds left: " + (millisUntilFinished)
/ 1000);
}
public void onFinish()
{
TextTimer.setText("Finished!");
}
};
}
public void onStart(Intent intent, int startid)
{
Log.d(TAG, "on-Start");
mt.start();
}
public void onDestroy()
{
Log.d(TAG, "on-Stop");
mt.stop();
}
public static class MyThread extends Thread
{
public void run()
{
try
{
while (state = true)
{
MyThread.sleep(500);
}
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
};
}
}
#Override
public IBinder onBind(Intent intent)
{
// TODO Auto-generated method stub
return null;
}
}
Have a static Handler in Your Activity which receives your Message of Tick and Finish
In the Service have a Thread which start the CountDown So that your CountDown will be working at your Thread not in the Main Thread.
You can use TimerTask Class for such purpose. It is same as thread , but allows you to perform a task based on Time Interval. you can also perform repeatable task in its run method.
Please check simple example here.
First off: You shouldn't run the CountDownTimer in the applications UI thread, since that could cause ANRs (Application not responding) issues.
You can use the SheduledThreadPoolExecutor with your custom Runnable or use a Bound Service. To call back the actual activity (if it's running, you could use different methods like subscribing via the Observer Pattern or send around Intents using the LocalBroadcastManager and then update the UI in it's own thread.
You may also use TimerTask as Lucifer has pointed out, but make sure the Runnable calls runOnUiThread when updating views.