How do i make Android app which do something every X second
Solution 1
I have alter the code by following
There are 3 ways all of them working(showing Log output).
But TextView isn't updating. Why?
package cz.cvut.fel.android;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
public class App5_RepeatedAction extends Activity {
static TextView tv1;
static class MyThread implements Runnable {
public void run() {
boolean end = false;
while (!end) {
String txt = "Vlakno id:" + Thread.currentThread().getId()+" THREAD";
Log.v("MyActivity", txt);
//tv1.setText(txt);
showTime(tv1);
try {
Thread.sleep(10000);
} catch (InterruptedException ex) {
System.err.println(ex.toString());
}
}
}
}
static void showTime(TextView tv1 ){
String DATE_FORMAT_NOW = "yyyy-MM-dd HH:mm:ss";
Calendar cal = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT_NOW);
tv1.setText(sdf.format(cal.getTime())+" "+System.currentTimeMillis());
}
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
tv1 = (TextView) findViewById(R.id.tv);
//----------ScheduledExecutorService
ScheduledExecutorService exec = Executors.newSingleThreadScheduledExecutor();
exec.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
String txt = "ScheduledExecutorService";
Log.v("MyActivity", txt);
//tv1.setText(txt);
showTime(tv1);
}
}, 0, 5, TimeUnit.SECONDS);
//----------TIMER
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
String txt = "Timer";
Log.v("MyActivity", txt);
//tv1.setText(txt);
showTime(tv1);
}
}, 0, 1000);
//-----------THREAD
try {
boolean quit = false;
Thread t = new Thread(new MyThread());
//t.setDaemon(true);
t.start();
} catch (Exception e) {
System.err.println(e.toString());
}
}
}
Solution 2
You don't have a loop in run() function, try to change it like this:
@Override
public void run() {
TextView tv1 = (TextView) findViewById(R.id.tv);
while(true){
showTime(tv1);
try {
Thread.sleep(1000);
}catch (Exception e) {
tv1.setText(e.toString());
}
}
}
Be careful, it will run forever though. You should also use a handler to perform changes on UI from another thread, it can be done by example below:
Handler mHandler = new Handler();
@Override
public void run() {
final TextView tv1 = (TextView) findViewById(R.id.tv);
while(true){
try {
mHandler.post(new Runnable(){
@Override
public void run() {
showTime(tv1);
}
);
Thread.sleep(1000);
}catch (Exception e) {
//tv1.setText(e.toString());
}
}
}
Solution 3
Like I said before, you got to modify your textView in the UI thread (the thread that created the component).
In order to do that use a Handler, like this : (Do not loop in your thread, just post a message to the handler)
private TextView tv1;
Handler tick_Handler = new Handler();
MyThread tick_thread = new MyThread();
private class MyThread implements Runnable {
public void run() {
String txt = "Vlakno id:" + Thread.currentThread().getId()+" THREAD";
Log.v("MyActivity", txt);
//tv1.setText(txt);
showTime(tv1);
tick_Handler.postDelayed(tick_thread, 1000);
}
}
String DATE_FORMAT_NOW = "yyyy-MM-dd HH:mm:ss";
SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT_NOW);
private void showTime(TextView tv ){
Calendar cal = Calendar.getInstance();
tv.setText(sdf.format(cal.getTime())+" "+System.currentTimeMillis());
}
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
tv1 = (TextView) findViewById(R.id.tv);
tick_Handler.post(tick_thread);
}
By the way, if you want to have an accurate timer, you should tick every 300 ms. You might see some strange seconds if you perform your "showtime" method every second.
Solution 4
It seems that you have two problems here.
1 - If you do not have a loop in your thread, the "showtime" method will be called just once.
2 - Modifying a UI component from a thread different to the main thread will fail.
You should find what you want here : http://developer.android.com/resources/articles/timed-ui-updates.html
Tom
Updated on June 14, 2022Comments
-
Tom almost 2 years
Hello i wanna do apliacation which every 1 second call function or do something else. I have this code which is not working can you tell what is wrong?
public class App5_Thread extends Activity implements Runnable { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); Thread thread = new Thread(this); thread.start(); } @Override public void run() { TextView tv1 = (TextView) findViewById(R.id.tv); showTime(tv1); try { Thread.sleep(1000); }catch (Exception e) { tv1.setText(e.toString()); } } public void showTime(TextView tv1 ){ String DATE_FORMAT_NOW = "yyyy-MM-dd HH:mm:ss"; Calendar cal = Calendar.getInstance(); SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT_NOW); tv1.setText(sdf.format(cal.getTime())+" "+System.currentTimeMillis()); }
}
-
Jonathan almost 13 yearsBecause the lines to update the TextView are commented out...?
-
Adil Malik over 10 yearsThis will keep the processor and other resources busy. I'd recommend using
Handler
.