2012-07-21 95 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