Question

I have this ToggleButton that is enabled when a certain condition (Website content) is true.

getSystemOnState(..) connects to a webserver and this causes an exception because of strict mode. What is wrong about the way I am using the Handler class?

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();
 }
}
Was it helpful?

Solution

Strict mode is complaining because you are still trying to do that network operation on the UI thread. Or this class is getting called into by a BroadcastReceiver (which are short lived). Handlers's are also ment to pass messages and you aren't really using them correctly in this example. Or at least you can see how all the Threads, runnables, and posting makes everything hard to read.

What you need here is AsyncTask.

Here is the Google example From 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);

In your case, you will want the first parameter to be your host string, your do in background will perform your checks and your network call, and the onPostExecute (which runs on the UI thread) to update your views.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top