2012-02-02 101 views
0

我試圖測量無線信號強度5次(每秒後)&在TextView中顯示它。我同時也將它寫入外部存儲器。 除了我無法實時看到結果外,一切運行正常。該應用程序將運行5秒,並顯示一個空白的屏幕,然後顯示結果(這是正確的順便說一句,即5秒後不同的讀數)。 我希望在for循環的每次迭代中儘快計算新值,以便更新結果。 感謝 下面是代碼UI不會實時更新

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"); 
         } 

      } 
     }); 
    } 
} 
} 

回答

1

你可以嘗試創建一個處理程序來處理在主線程UI更新任務。不要在線程中更新UI,而是通過傳遞處理程序消息來確保在主線程中處理此作業。這對我來說可以。我已經修改了一些代碼在這裏(我刪除了寫文件的一部分),

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(); 
    } 

} 
+0

真棒......謝謝! – shiraz 2012-02-02 02:05:15

1

問題是你說的沒錯,試圖做你的更新在獨立的Runnable ...但是做的事情,你的Runnable在UI線程中運行,因此導致UI線程位於循環中(包括Thread.sleep())。你沒有得到你的更新,因爲你讓UI等着你。

如果您的處理相當繁重,您可能希望將其分解爲單獨的線程並將消息發送給處理程序。否則,它可能是最容易做像以下(未經測試,但類似的東西):

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); 
}