How do i make Android app which do something every X second

13,499

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

Share:
13,499
Tom
Author by

Tom

Updated on June 14, 2022

Comments

  • Tom
    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
    Jonathan almost 13 years
    Because the lines to update the TextView are commented out...?
  • Adil Malik
    Adil Malik over 10 years
    This will keep the processor and other resources busy. I'd recommend using Handler.