shiraz
shiraz

Reputation: 1218

UI won't update in real time

I am trying to measure the wifi signal strength 5 times (after every second) & display it in a TextView. I simultaneously write it to external storage as well. Everything runs fine except that I am NOT able to see the results in real time. The app would run for 5 secs with a blank screen and then show up the results (which are correct btw, i.e 5 different readings after each second). I'd want to see the results updating as soon the new value is calculated in each iteration of the for loop. Thanks Here is the code

public class WifiDemo extends Activity implements OnClickListener {
private static final String TAG = "WiFiDemo";
WifiManager wifi;
TextView textStatus;
Button buttonScan;

/** Called when the activity is first created. */
/*
 * (non-Javadoc)
 * 
 * @see android.app.Activity#onCreate(android.os.Bundle)
 */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    // Setup UI
    textStatus = (TextView) findViewById(R.id.textStatus);
    buttonScan = (Button) findViewById(R.id.buttonScan);
    buttonScan.setOnClickListener(this);

    // Setup WiFi
    wifi = (WifiManager) getSystemService(Context.WIFI_SERVICE);
    String state = Environment.getExternalStorageState();
    if (Environment.MEDIA_MOUNTED.equals(state)) {
            // Get WiFi status
            runOnUiThread(new Runnable() {
                public void run() {
                    try {
                    FileWriter fw = new FileWriter(
                            Environment.getExternalStorageDirectory()
                                    + "/bluetooth/wifi.txt");

                    for (int i = 0; i < 5; i++) {
                        WifiInfo info = wifi.getConnectionInfo();
                        Date d = new Date(System.currentTimeMillis());
                        String stat = "\n\nWiFi Status: " + info.getRssi()
                                + " " + d.getHours() + ":" + d.getMinutes()
                                + ":" + d.getSeconds();
                        textStatus.append(stat);
                        fw.write(stat);
                        fw.flush();
                        try {
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                    }


                    fw.close();

                }
                     catch (IOException e1) {
                            // TODO Auto-generated catch block
                            e1.printStackTrace();
                            textStatus.append("something wrong");
                        }

            }
        });
    }
}
}

Upvotes: 0

Views: 2123

Answers (2)

Brian Dupuis
Brian Dupuis

Reputation: 8176

The problem is you're doing something right by trying to do your updating in a separate Runnable... however, your Runnable is running in the UI thread and therefore causing the UI thread to sit in the loop (including the Thread.sleep()). You're not getting your updates because you're causing the UI to wait on you.

If your processing is reasonably heavy, you might wish to break it out into a separate thread and send messages to a handler. Otherwise, it might be easiest to do something like the following (untested, but something similar):

if (Environment.MEDIA_MOUNTED.equals(state)) {
    textStatus.postDelayed(new Runnable() {
        public void run() {
            WifiInfo info = wifi.getConnectionInfo();
            Date d = new Date(System.currentTimeMillis());
            String stat = "\n\nWiFi Status: " + info.getRssi()
                            + " " + d.getHours() + ":" + d.getMinutes()
                            + ":" + d.getSeconds();
            textStatus.append(stat);

            // relaunch if we're not through with our number of iterations.
            // mCount is a new field.
            if(mCount++ < 5) {
                textStatus.postDelayed(this, 1000);
            }
        }
    }, 1000);
}

Upvotes: 1

Berby Huang
Berby Huang

Reputation: 166

You can try to create a handler to handle UI update tasks in the main thread. Do not update UI in your thread, instead, do it by passing handler messages to make sure this job is handled in the main thread. It works fine for me. I've modified some of your code here (I removed the write file part),

public class WifiDemo extends Activity implements OnClickListener {

private static final String TAG = "WiFiDemo";
private static final int WifiDetectStart = 0;
private static final int WifiDetectStop = 1;
private String stat;
WifiManager wifi;
TextView textStatus;
Button buttonScan;
Handler handler;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

 // Setup UI
    textStatus = (TextView) findViewById(R.id.textStatus);
    buttonScan = (Button) findViewById(R.id.buttonScan);
    buttonScan.setOnClickListener(this);

 //setup handler

    handler = new Handler(){

        @Override
        public void handleMessage(Message msg) {

            if(msg.what == WifiDetectStart)
            {
                textStatus.append(stat);
            }

            if(msg.what == WifiDetectStop)
            {
                Thread.currentThread().interrupt();
            }

            super.handleMessage(msg);
        }  
       };

 // Setup WiFi
    wifi = (WifiManager) getSystemService(Context.WIFI_SERVICE);
    String state = Environment.getExternalStorageState();
    if (Environment.MEDIA_MOUNTED.equals(state)) {
            // Get WiFi status

            Thread myThread = new Thread(new Runnable() {
                public void run() {
                    for (int i = 0; i < 5; i++) {
                        WifiInfo info = wifi.getConnectionInfo();
                        Date d = new Date(System.currentTimeMillis());
                        stat = "\n\nWiFi Status: " + info.getRssi()
                                + " " + d.getHours() + ":" + d.getMinutes()
                                + ":" + d.getSeconds();
                        Message msg = new Message();
                        msg.what = WifiDetectStart;
                        handler.sendMessage(msg);
//                      textStatus.append(stat);
                        try {
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                    }

                    //finish this operation
                    Message msg = new Message();
                    msg.what = WifiDetectStop;
                    handler.sendMessage(msg);
                }
        });
            myThread.start();
    }

}

Upvotes: 1

Related Questions