2012-07-21 91 views
0

我有這個ToggleButton,當某個條件(網站內容)爲true時啓用。Android StrictMode:這個示例的錯誤肯定或錯誤?

getSystemOnState(..)連接到一個網絡服務器,這會導致由於嚴格模式的異常。我使用Handler類的方式有什麼問題?

public class ReceiverToggleButton extends ToggleButton { 
private Runnable mTicker; 
private Handler mHandler; 
private boolean mTickerStopped = false; 
private String rxhost = null; 
private Context context = null; 

public ReceiverToggleButton(Context context) { 
    super(context); 
    this.context = context; 
    updateOnOffState(context); 
} 

private void updateOnOffState(final Context cxt) { 
    Runnable r = new Runnable() { 
     public void run() { 
      rxhost = cxt.getResources().getString(R.string.host_receiver); 
      mHandler = new Handler(); 
      mTicker = new Runnable() { 
       public void run() { 
        if (mTickerStopped) { 
         return; 
        } 

        boolean isSystemOn = getSystemOnState(rxhost); // connects to webserver 
        setChecked(isSystemOn); 
        invalidate(); 
        long now = SystemClock.uptimeMillis(); 
        long next = now + 1000 * 10; // check every 10s 
        mHandler.postAtTime(this, next); 
       } 

      }; 
      mHandler.post(mTicker); 
     } 
    }; 
    new Thread(r).start(); 
} 
} 

回答

1

嚴格模式是抱怨,因爲您仍然試圖在UI線程上執行該網絡操作。或者這個類正在被BroadcastReceiver調用(這是短暫的)。 處理程序也傳遞消息,在這個例子中你並沒有真正使用它們。或者至少你可以看到所有的線程,可運行參數和發佈如何使一切難以閱讀。

你所需要的是什麼的AsyncTask。

這是谷歌的例子從http://developer.android.com/reference/android/os/AsyncTask.html

private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> { 
    protected Long doInBackground(URL... urls) { 
     int count = urls.length; 
     long totalSize = 0; 
     for (int i = 0; i < count; i++) { 
      totalSize += Downloader.downloadFile(urls[i]); 
      publishProgress((int) ((i/(float) count) * 100)); 
      // Escape early if cancel() is called 
      if (isCancelled()) break; 
     } 
     return totalSize; 
    } 

    protected void onProgressUpdate(Integer... progress) { 
     setProgressPercent(progress[0]); 
    } 

    protected void onPostExecute(Long result) { 
     showDialog("Downloaded " + result + " bytes"); 
    } 
} 

new DownloadFilesTask().execute(url1, url2, url3); 

在你的情況,你會希望第一個參數是你的主機字符串,你在後臺做將執行你的支票和網絡通話,並且onPostExecute (在UI線程上運行)來更新您的視圖。

+0

謝謝!現在,我只是想知道我怎麼會正確使用處理程序 - 我用這個[教程](http://www.vogella.com/articles/AndroidPerformance/article.html#concurrency_asynchtask),我看不到我在做什麼不同。 – PhilW 2012-07-21 16:23:48

+0

是的。我想這種方式很有效,但不是很乾淨。根據我的經驗,當你有兩個類(通常在不同的線程中)需要彼此交談時,處理程序很好。例如,MusicService嘗試將更新發送回活動。 (另一種方式可以只使用一個IntentService)所以我想我只通過單向的小信息(通常是ID)進行通信並且執行一些動作,取得了巨大的成功。 – 2012-07-21 16:29:09

+0

這與我的用例(不是發佈的,但是相同的應用程序)稍有不同。我有一個顯示當前在遠程系統上播放的歌曲(通過HTTP查詢的XBMC)的文本視圖。因此,每隔N秒我想查詢XBMC並顯示歌曲的名稱。我目前的方法是現在的AsyncTasks,使用java.util.TimerTasks進行計劃 - 我會看看是否可行。 – PhilW 2012-07-21 16:37:01