×

Discussion Board

Results 1 to 5 of 5
  1. #1
    Regular Contributor
    Join Date
    Nov 2009
    Posts
    53

    Angry Text update causing screen fliker

    Hello,

    I am using the Form class and StringItem class to display text on the screen. When I update the StringItem inside a thread using setText my phone (E60) updates the text however, the whole area represented by the string item 'flikers' inorder to refresh the text and the background.

    The same also occurs when updating text in the foreground.

    The same application running on a E71 does not suffer from this problem. Is there a way to update the text without the screen flikering?

    Here is a simple example:

    private void InitDisplay()
    {
    // Init Display
    if (display == null) {
    display = Display.getDisplay(this);
    midletForm = new Form("GSM info");
    }
    midletForm.append(TxtRSSI);
    midletForm.addCommand(CMD_EXIT);
    ...
    midletForm.setCommandListener(this);
    display.setCurrent(midletForm);

    // Init Thread
    StartThread = true;
    EnableRefresh = true;

    t = new Thread(this);
    t.setPriority(t.NORM_PRIORITY);
    t.start();
    }

    private void SignelDetails()
    {
    // Obtain the latest information:
    gprs.RefreshData(false);

    // update the text with the latest into:
    // This is where I have
    TxtRSSI.setText(String.valueOf(gprs.SignaldBm) + "dBm (" + gprs.SignalPercent + "%)");

    // Do I need this?
    if (display.getCurrent() == midletForm){
    display.setCurrent(midletForm);
    }
    }


    public void run() {
    while(StartThread){
    if (EnableRefresh)
    {
    SignelDetails();
    Thread.yield(); // Would this help to reduce the screen fliker?

    // Delay the next update for a specified amount of time eg. 1 sec, 2 sec etc.
    try {
    Thread.sleep(RefreshRate);
    } catch(Exception e) {}
    }
    else
    {
    // No work to do yield thread.
    Thread.yield();
    }
    }
    }

  2. #2
    Super Contributor
    Join Date
    Jun 2003
    Location
    Cheshire, UK
    Posts
    7,395

    Re: Text update causing screen fliker

    There probably isn't much you can do, since this is down to the implementation of Form. You might have more joy using a Canvas.

    Oh... beware of Thread.yield(). If there is no higher priority thread to run, this will just return. In your code, if EnableRefresh is false, the loop in run() will consume huge amounts of CPU time. Change it to something like:

    Code:
    public void run() {
        while(StartThread) {
            if (EnableRefresh) {
                SignelDetails();
            }
    
            // Delay the next update for a specified amount of time eg. 1 sec, 2 sec etc.
            try {
                Thread.sleep(RefreshRate);
            } catch(Exception e) {
                // ignore
            }
        }
    }
    Graham.

  3. #3
    Regular Contributor
    Join Date
    Nov 2009
    Posts
    53

    Re: Text update causing screen fliker

    Thanks for you reply Graham, I am not really working with graphics and would like to keep things simple if possible. This happens to be my first project.

    Is it easy to use a canvas?

    I have another query, I am unable to restart my thread after I have compleated some GPRS Comms. I am using the following code to start and stop my thread at appropriate points in my code. Before I make a GPRS call I terminate my thread by calling StopThread() and re-start my thread by calling StartThread().

    Is there any reason why this thread won't re-start following some GPRS Comms? My Comms code also uses threads - there are no issues here.

    Code:
    public class GSMInfo extends MIDlet implements Runnable, CommandListener {
    {
        Thread t=null;
        boolean StartThread;
        boolean EnableRefresh;
        // Other class members
    
        private void StartThread()
        {
            // t is defined as a member of this class.
            if (t == null)
            {
                t = new Thread(this);
                t.setPriority(t.NORM_PRIORITY);
            }
            
            StartThread = true;                 // Start thread:
            t.start();
        }
    
        private void StopThread()
        {
            StartThread = false;
        }
    }
    Last edited by dharmeshkhatri; 2010-04-08 at 13:21.

  4. #4
    Super Contributor
    Join Date
    Jun 2003
    Location
    Cheshire, UK
    Posts
    7,395

    Re: Text update causing screen fliker

    Quote Originally Posted by dharmeshkhatri View Post
    Is it easy to use a canvas?
    It's not difficult, but it's not as easy as using a Form. In particular, it won't wrap text for you.


    Quote Originally Posted by dharmeshkhatri View Post
    I am unable to restart my thread
    Threads are not re-startable, they're "single-use". Once a thread has stopped, you need to create a new one.

    Quote Originally Posted by dharmeshkhatri View Post
    Code:
        Thread t=null;
        boolean StartThread;
        boolean EnableRefresh;
    I suggest you make these (and any other members) private. They're not private by default, and you really need a very, very good reason to make member variables non-private (it's almost always a bad idea).

    In this case, variables like StartThread and EnableRefresh are shared between threads, so should be marked as "volatile". If a member variable is not volatile, threads are allowed to keep private, cached copies of their values, for performance reasons. This can cause them to miss a change made to a variable by another thread. The "volatile" keyword tells any thread that accesses a variable that it it likely to be modified by another thread.

    (You might like to read the Sun Java Coding Conventions... Java programmers don't usually use capital letters at the start of variable or method names, only for class names. We get confused when we see code that doesn't follow the convention, because it looks like you're referring to a class when you're not!)

    I end up with:

    Code:
    public class GSMInfo extends MIDlet implements Runnable, CommandListener {
        private Thread thread;
        private volatile boolean startThread;
        private volatile boolean enableRefresh;
    
        private void startThread() {
            if (startThread == false) {
                // if a thread is still running, wait for it to die
                while (thread != null && thread.isAlive()) {
                    try {
                        Thread.sleep(15);
                    } catch (InterruptedException ie) {
                        // ignore
                    }
                }
                // now start a new one
                startThread = true;
                thread = new Thread(this);
                thread.start();
            } else {
                throw new IllegalStateException("thread already started");
            }
        }
    
        private void stopThread() {
            if (startThread == true) {
                startThread = false;
            } else {
                throw new IllegalStateException("thread not started");
            }
        }
    }
    I've just knocked this code up while writing the message, so forgive me if there's a compiler error!

    I don't bother setting the priority. NORMAL will be the default, and some implementations don't actually honour priority anyway (all threads might run at the same priority). Two things to notice:

    1. I throw exceptions if startThread() is called while the thread is running, or stopThread() is called when it's already stopped. This can help you find logic bugs in the code.

    2. Before starting a new thread, startThread() now waits to make sure that the old thread has died. If you don't do this, then calling stopThread() and startThread() in rapid succession can result in having two threads running at the same time. For example, the startThread variable gets set to false while the thread is sleeping, and then it gets set back to true before the thead wakes up... the thread never sees the "false", so it carries on running.

    (You could add "thread.interrupt()" to try to wake up the thread, and get it to die faster, but remember that the method Thread.interrupt() only exists in CLDC-1.1, so you'd lose compatibility with CLDC-1.0 devices.)

    Graham.

  5. #5
    Nokia Developer Champion
    Join Date
    Feb 2009
    Location
    Noida, India
    Posts
    3,073

    Re: Text update causing screen fliker

    I am not really working with graphics and would like to keep things simple if possible. This happens to be my first project.

    Is it easy to use a canvas?
    If you are not really working with graphics, You can try using LWUIT, the forms in LWUIT provide almost all Canvas like features.

    thanks,
    ~Amitabh

Similar Threads

  1. Show text on the celular screen
    By carlus1 in forum Python
    Replies: 2
    Last Post: 2008-03-08, 11:51
  2. I need to get the text on screen
    By guowen in forum Symbian C++
    Replies: 6
    Last Post: 2008-01-30, 09:53
  3. Can't update counts of text sms!
    By localizationer in forum Symbian C++
    Replies: 4
    Last Post: 2007-11-20, 10:14
  4. Please Help:: Update Label Text
    By nong_koh in forum Symbian User Interface
    Replies: 3
    Last Post: 2007-05-23, 10:50
  5. Replies: 0
    Last Post: 2002-05-17, 12:09

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •