TextView setText ignoring changes?

Put problem concerning Views, Layouts and other XML-Resources (like AndroidManifest) here.

TextView setText ignoring changes?

Postby ClockworkAlchemist » Wed Mar 04, 2009 5:29 pm

I'm trying to put a simple timer at the top of my application. My idea was to dislpay it in a TextView and run a TimerTask and periodically update the timer. That all seems to work fine, but the text displayed in the TextView doesn't update after the first time I call setText. I've even tried calling invalidate and some other random voodoo, with no luck. I've tried spitting out the string to the debugger, and it is getting generated correctly roughly every second.
I assume I must be doing some very simple thing incorrectly. Is there some reason why my text view won't refresh?


Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1.  
  2.  
  3.  
  4. import stuff here
  5.  
  6.  
  7.  
  8. public class ClockActivity extends Activity
  9.  
  10. {
  11.  
  12.         long start_time = System.currentTimeMillis();
  13.  
  14.         TextView text_timer = null;
  15.  
  16.        
  17.  
  18.        
  19.  
  20.     /** Called when the activity is first created. */
  21.  
  22.     @Override
  23.  
  24.     public void onCreate(Bundle savedInstanceState)
  25.  
  26.     {
  27.  
  28.         super.onCreate(savedInstanceState);
  29.  
  30.         setContentView(R.layout.dttb_activity);
  31.  
  32.                
  33.  
  34.         start_time = System.currentTimeMillis();        
  35.  
  36.         text_timer = (TextView) findViewById(R.id.text_timer);
  37.  
  38.        
  39.  
  40.         Timer timer = new Timer();
  41.  
  42.        
  43.  
  44.         TimerTask task = new TimerTask()
  45.  
  46.         {
  47.  
  48.                 public void run()
  49.  
  50.                 {
  51.  
  52.                         updateClock();
  53.  
  54.                 }
  55.  
  56.         };
  57.  
  58.        
  59.  
  60.         timer.scheduleAtFixedRate(task, 0, 1000);
  61.  
  62.        
  63.  
  64.  
  65.  
  66.     }
  67.  
  68.  
  69.  
  70.    
  71.  
  72.     public void updateClock()
  73.  
  74.     {
  75.  
  76.         long current_time = System.currentTimeMillis();
  77.  
  78.         long elapsed_time = current_time - start_time;
  79.  
  80.         Date elapsed = new Date(elapsed_time);
  81.  
  82.        
  83.  
  84.         int hours = elapsed.getHours();
  85.  
  86.         int minutes = elapsed.getMinutes();
  87.  
  88.         int seconds = elapsed.getSeconds();
  89.  
  90.        
  91.  
  92.         String message = String.format("%3d:%02d:%02d", hours, minutes, seconds);
  93.  
  94.  
  95.  
  96.         // This line works the first time this is called,
  97.  
  98.         // but doesn't show changes on later calls....
  99.  
  100.         text_timer.setText( message );
  101.  
  102.  
  103.  
  104.         // uncomment for debugging
  105.  
  106.         //System.out.println(message);
  107.  
  108.     }
  109.  
  110. }
  111.  
  112.  
Parsed in 0.034 seconds, using GeSHi 1.0.8.4



Here is my layout file, pretty simple....


Syntax: [ Download ] [ Hide ]
Using xml Syntax Highlighting
  1.  
  2.  
  3.  
  4. <?xml version="1.0" encoding="utf-8"?>
  5.  
  6. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  7.  
  8.    android:orientation="vertical"
  9.  
  10.    android:layout_width="fill_parent"
  11.  
  12.    android:layout_height="fill_parent"
  13.  
  14.    android:background="#ffffffff"
  15.  
  16.    >
  17.  
  18.  
  19.  
  20.        
  21.  
  22. <TextView
  23.  
  24.         android:id="@+id/text_timer"
  25.  
  26.         android:layout_width="wrap_content"
  27.  
  28.         android:layout_height="wrap_content"    
  29.  
  30.         android:text="000:00:00:00"
  31.  
  32.         android:textSize="24sp"
  33.  
  34.         android:textStyle="bold"
  35.  
  36.         android:layout_gravity="center_horizontal|top"
  37.  
  38.         android:textColor="#ff000000" />
  39.  
  40.  
  41.  
  42.  
  43.  
  44. </LinearLayout>
  45.  
  46.  
Parsed in 0.002 seconds, using GeSHi 1.0.8.4
ClockworkAlchemist
Junior Developer
Junior Developer
 
Posts: 14
Joined: Sun Feb 08, 2009 3:41 am
Location: Orange County, CA

Top

Postby ClockworkAlchemist » Tue Mar 10, 2009 5:21 am

So I played around with this for awhile, and it turns out that you don't want to call setText on a thread other than the UI thread. I changed my code to this to get it to work:

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1.  
  2.  
  3.  
  4.  
  5.  
  6. public class ClockActivity extends Activity
  7.  
  8. {
  9.  
  10.         private class UpdateClock implements Runnable
  11.  
  12.         {
  13.  
  14.                ClockActivity act = null;
  15.  
  16.                 public void run()
  17.  
  18.                 {
  19.  
  20.                        if ( act != null && !act.isFinishing() )
  21.  
  22.                        {
  23.  
  24.                             act.updateClock();
  25.  
  26.                        }
  27.  
  28.                 }
  29.  
  30.         }
  31.  
  32.        
  33.  
  34.         private class ClockTask extends TimerTask
  35.  
  36.         {
  37.  
  38.                 ClockActivity act = null;
  39.  
  40.                 public void run()
  41.  
  42.                 {
  43.  
  44.                      if ( act != null && !act .isFinishing() )
  45.  
  46.                      {
  47.  
  48.                             UpdateClock update = new UpdateClock();
  49.  
  50.                             update.act = this.act ;
  51.  
  52.                             act .runOnUiThread(update);
  53.  
  54.                      }
  55.  
  56.                 }
  57.  
  58.         }
  59.  
  60.        
  61.  
  62.         long start_time = System.currentTimeMillis();
  63.  
  64.         Timer clock_timer = null;
  65.  
  66.        
  67.  
  68.     /** Called when the activity is first created. */
  69.  
  70.     @Override
  71.  
  72.     public void onCreate(Bundle savedInstanceState)
  73.  
  74.     {
  75.  
  76.         super.onCreate(savedInstanceState);
  77.  
  78.         setContentView(R.layout.clock_activity);              
  79.  
  80.  
  81.  
  82.         start_time = System.currentTimeMillis();
  83.  
  84.        
  85.  
  86.         clock_timer = new Timer();
  87.  
  88.        
  89.  
  90.         ClockTask clock_task = new ClockTask();
  91.  
  92.         clock_task.act = this;
  93.  
  94.  
  95.  
  96.         clock_timer.scheduleAtFixedRate(clock_task, 0, 1000);
  97.  
  98.     }
  99.  
  100.    
  101.  
  102.  
  103.  
  104.    
  105.  
  106.     public void updateClock()
  107.  
  108.     {
  109.  
  110.         long current_time = System.currentTimeMillis();
  111.  
  112.         long elapsed_time = current_time - start_time;
  113.  
  114.         Date elapsed = new Date(elapsed_time);
  115.  
  116.        
  117.  
  118.         int hours = elapsed.getHours();  
  119.  
  120.         int minutes = elapsed.getMinutes();
  121.  
  122.         int seconds = elapsed.getSeconds();
  123.  
  124.        
  125.  
  126.         String message = String.format("%3d:%02d:%02d", hours, minutes, seconds);
  127.  
  128.  
  129.  
  130.         TextView text_timer = (TextView) findViewById(R.id.text_timer);
  131.  
  132.         text_timer.setText(message);
  133.  
  134.  
  135.  
  136.         // uncomment for debugging
  137.  
  138.        // System.out.println(message);
  139.  
  140.     }
  141.  
  142. }
  143.  
  144.  
  145.  
  146.  
  147.  
  148.  
Parsed in 0.037 seconds, using GeSHi 1.0.8.4



However, this just feels like a tremendous hack. Also, the virtual machine reports that its cleaning up around 10,000 objects and about 500kb every 30 seconds or so, which seems ridiculous for such a simple app. Can anybody suggest a better way of doing this?
ClockworkAlchemist
Junior Developer
Junior Developer
 
Posts: 14
Joined: Sun Feb 08, 2009 3:41 am
Location: Orange County, CA

solution

Postby powerdeng » Tue Mar 10, 2009 7:47 pm

You should only update a UI object in the main thread.
send a message when you need to refresh the UI ,and use a handler to react.
the code below maybe do what you want.
[modified from your code,i use the default layout name .lazy :)]

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1. public class ClockActivity extends Activity
  2.  
  3. {
  4.  
  5.      long start_time = System.currentTimeMillis();
  6.  
  7.      TextView text_timer = null;
  8.  
  9.      
  10.  
  11.      /*in order to refer everywhere*/
  12.  
  13.      String message;
  14.  
  15.      
  16.  
  17.      /*Use handler to receive message from other thread*/
  18.  
  19.      Handler updateNow;
  20.  
  21.      
  22.  
  23.      /*Your Message 'what'*/
  24.  
  25.      public static final int TICK = 1;
  26.  
  27.      
  28.  
  29.     /** Called when the activity is first created. */
  30.  
  31.     @Override
  32.  
  33.     public void onCreate(Bundle savedInstanceState)
  34.  
  35.     {
  36.  
  37.         super.onCreate(savedInstanceState);
  38.  
  39.         setContentView(R.layout.main);
  40.  
  41.                
  42.  
  43.         start_time = System.currentTimeMillis();        
  44.  
  45.         text_timer = (TextView) findViewById(R.id.text_timer);
  46.  
  47.         /*You own handler hear*/
  48.  
  49.         updateNow = new Handler() {
  50.  
  51.             @Override
  52.  
  53.             public void handleMessage(Message msg) {
  54.  
  55.                 switch (msg.what) {
  56.  
  57.                 case TICK:
  58.  
  59.                     text_timer.setText(message);
  60.  
  61.                 }
  62.  
  63.             }
  64.  
  65.         };
  66.  
  67.         Timer timer = new Timer();
  68.  
  69.        
  70.  
  71.         TimerTask task = new TimerTask()
  72.  
  73.         {
  74.  
  75.           public void run()
  76.  
  77.           {
  78.  
  79.                updateClock();
  80.  
  81.           }
  82.  
  83.         };
  84.  
  85.        
  86.  
  87.         timer.scheduleAtFixedRate(task, 0, 1000);        
  88.  
  89.     }
  90.  
  91.  
  92.  
  93.    
  94.  
  95.     public void updateClock()
  96.  
  97.     {
  98.  
  99.      long current_time = System.currentTimeMillis();
  100.  
  101.      long elapsed_time = current_time - start_time;
  102.  
  103.      Date elapsed = new Date(elapsed_time);
  104.  
  105.      
  106.  
  107.      int hours = elapsed.getHours();
  108.  
  109.      int minutes = elapsed.getMinutes();
  110.  
  111.      int seconds = elapsed.getSeconds();
  112.  
  113.      
  114.  
  115.      /*Change the message and tell the UI thread to update*/
  116.  
  117.      message = String.format("%3d:%02d:%02d", hours, minutes, seconds);
  118.  
  119.      updateNow.sendEmptyMessage(TICK);
  120.  
  121.     }
  122.  
  123. }
Parsed in 0.039 seconds, using GeSHi 1.0.8.4
:) e2ecloud.com
powerdeng
Freshman
Freshman
 
Posts: 9
Joined: Mon Feb 16, 2009 10:20 am
Location: Chengdu,China

Top

Return to View, Layout & Resource Problems

Who is online

Users browsing this forum: Exabot [Bot] and 4 guests