1

I'm trying to make a program that monitors network connectivity, one that shows statuses and bandwidth and refreshes every second. Yesterday I learned that network monitoring occurs on a secondary thread, which I created; it now works.

I believe to have the program refresh every second, I do a while-loop, in which the while-condition is always "true", and at the end of the while loop I "try" a Thread.sleep(1000).

I have one question and one problem.

Question: Do I risk flooding my program? I feel like by setting secondaryThread = null, all the data created during the while loop gets garbage collected, but I'm not sure whether this is the case.

Problem: When I run this, I get a message "[Program] has quit unexpectedly"... leading me to think that I am indeed flooding the program. Is there a way to get around this?

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    int linkSpeed = -1;
    TextView textView = new TextView(this);
    while (true)
    {
        SecondaryThread secondaryThread = new SecondaryThread(this);
        new Thread(secondaryThread).start();
        linkSpeed = secondaryThread.getLinkSpeed();
        secondaryThread = null;

        // Create the text view
        textView.setTextSize(25);
        textView.setText("linkspeed = " + linkSpeed);

        // Set the text view as the activity layout
        setContentView(textView);
        try {
            Thread.sleep(1000);
        }
        catch (Exception e) {
            textView.setTextSize(25);
            textView.setText("oh shit");
        }
    }

The LogCat trace stack says everything is running fine, even though that's not the actual case. Specifically, it says the following...

06-27 15:07:58.069: D/gralloc_goldfish(1312): Emulator without GPU emulation detected.
06-27 15:41:45.879: I/dalvikvm(1919): threadid=3: reacting to signal 3
06-27 15:41:45.958: I/dalvikvm(1919): Wrote stack traces to '/data/anr/traces.txt'
Yuen Hsi
  • 143
  • 1
  • 4
  • 11
  • The logcat messages (reacting to signal 3, writing stack traces) don't necessarily indicate a problem. It just means something in the system thought it would be useful to grab the stack trace from process 1919 (possibly the ANR detector warming up). Look elsewhere in the log for reasons the process died -- search for the last occurrence of "1919" and look nearby. – fadden Jun 27 '13 at 23:40

2 Answers2

3

You never want to call Thread.sleep() on the UI Thread which it looks like you are doing here. You can put that in your Thread that you have created and use runOnUiThread() to update your TextView

Here is a SO answer that may help

This one also looks like what you are doing

Community
  • 1
  • 1
codeMagic
  • 44,549
  • 13
  • 77
  • 93
1

Never block the UI thread. Use background threads:

 protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    final TextView textView = new TextView(this);

    new AsyncTask<Void, Void, Void>() {

        @Override
        protected Void doInBackground(Void... params) {
            int globalState = 1;
            while (true) {
                // <cut>

                // Create the text view
                // new scope
                {
                final int linkSpeed = ++globalState;
                textView.post(new Runnable() {
                    @Override
                    public void run() {
                        textView.setTextSize(25);
                        textView.setText("linkspeed = " + linkSpeed);

                        // Set the text view as the activity layout
                        setContentView(textView);
                    }
                });
                }

                try {
                    Thread.sleep(1000);
                } catch (Exception e) {
                    textView.post(new Runnable() {
                        @Override
                        public void run() {
                            textView.setTextSize(25);
                            textView.setText("oh XXXX");
                        }
                    });
                }
            }
        }

    }.execute();
tofi9
  • 5,775
  • 4
  • 29
  • 50
  • the linkSpeed has to be final - so i don't think this works with my code; as linkSpeed is a variable that gets refreshed every second. – Yuen Hsi Jun 28 '13 at 20:46
  • linkSpeed needs to be final in the scope where you create the closure `Runnable() {...}`. However, nothing stops you from updating the value before you enter the scope, or create a new scope {...} – tofi9 Jun 29 '13 at 02:46