-1

I have designed an app that gets the network information and updates the UI every 5 seconds. It is advised to do the background processes on a separate thread than the UI thread, and I did so...but I still get an error that:

"I/Choreographer﹕ Skipped 3730 frames! The application may be doing too much work on its main thread."

Why is that? Here's my code

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    wifiTextView = (TextView)findViewById(R.id.wifi_textView);
    ipTextView = (TextView)findViewById(R.id.ip_val_textView);
    // and so on

    //Updating the UI every mInterval seconds, using a separate thread than UI thread
    Thread backgroundThread = new Thread() {
        @Override
        public void run() {
            try {
                while (!isInterrupted()) {
                    Thread.sleep(mInterval);
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            //Log.d(DEBUG_TAG, "run(): Background thread");
                            MyNetwork network = new MyNetwork(getApplicationContext());  // passing the context
                            updateUI(network);
                        }
                    });
                }
            } catch (InterruptedException e) {
                wifiTextView.setText("Exception: Please Close and Restart the App");
            }
        }
    };
    backgroundThread.start();

}

In the same MainActivity class, I have this private function:

 private void updateUI(MyNetwork network){
    // Handles updating the textviews in the UI
    //Log.d(DEBUG_TAG, "updateUI(DeepstreamNetwork)");

    if (network.isConnected()){
        wifiTextView.setText(R.string.wifi_is_on);
        wifiTextView.setTextColor(Color.GREEN);

        ipTextView.setText(network.getIpAddress());

    else {
        wifiTextView.setText(R.string.wifi_is_off);
        wifiTextView.setTextColor(Color.RED);

        ipTextView.setText("N/A");

    }
}

UPDATE

So, I have updated my MainActivity class to have this MyAsyncTask method to handle background work...here's my code:

private class MyAsyncTask extends AsyncTask<Void, Void, MyNetwork> {
    @Override
    protected void onPostExecute(MyNetwork network) {
        updateUI(network);
    }

    @Override
    protected MyNetwork doInBackground(Void... params) {
        MyNetwork network = new MyNetwork(getApplicationContext());  // passing the context
        return network;
    }

    @Override
    protected void onProgressUpdate(Void... values) {
        super.onProgressUpdate(values);
    }
}

Two issues:

1) how do I force it to do this background task every 5 seconds. Since the network status changes every few secs (disconnection etc...), so I want it to update the UI respectively.

2) should I call it like this in MainActivity: new MyAsyncTask().execute();

Thanks all

sorry_I_wont
  • 639
  • 1
  • 9
  • 16

1 Answers1

1

I dont know why you called it Thread backgroundThread = new Thread() because runOnUiThread() is really the main Thread.

You should try this in an asynctask where you only update the UI in onPostExecute()

EDIT:

private class MyAsyncTask extends AsyncTask<Void, Void, String> {

    private MyNetwork network;

    @Override
    protected void onPreExecute() {
        this.network = new MyNetwork(getApplicationContext()); 
    }

    @Override
    protected String doInBackground(Void... params) {
        return network.getIpAddress();
    }

    @Override
    protected void onPostExecute(String ipAddress) {
        if (this.network.isConnected()){
            wifiTextView.setText(R.string.wifi_is_on);
            wifiTextView.setTextColor(Color.GREEN);
            ipTextView.setText(ipAddress);
        else {
            wifiTextView.setText(R.string.wifi_is_off);
            wifiTextView.setTextColor(Color.RED);
            ipTextView.setText("N/A");
        }
    }

    @Override
    protected void onProgressUpdate(Void... values) {
        super.onProgressUpdate(values);
    }
}
meda
  • 45,103
  • 14
  • 92
  • 122
  • that should be network.getIpAdress() sorry I have another class, MyNetwork, that handles the background stuff, like getting the IP address, latency, signal level... – sorry_I_wont Jan 12 '16 at 01:55
  • `that handles the background stuff` You are doing this in the main thread use, async task instead. do you need an example? – meda Jan 12 '16 at 01:59
  • umm no there are lots of examples, and I implemented with AsyncTask first, but it wouldn't work, so I gave up and copy and pasted this piece of code I found on stackoverflow...I will switch to AsyncTask again, and if it didn't work again, I will let you know, thanks – sorry_I_wont Jan 12 '16 at 02:07
  • Yes please do, you would move `dsNetwork.getIpAddress()` to the `doInBackground()` and only update the textviews in `onPostExecute()` – meda Jan 12 '16 at 02:11
  • I have changed everything to AsyncTask, but now it doesn't update the UI every 5 seconds...this was my issue before...(should I define my AsyncTask in the same class as MainActivity?) – sorry_I_wont Jan 12 '16 at 19:45
  • yes you should, if the UI belongs there, then that's where it should be – meda Jan 12 '16 at 19:46
  • Ok, I did all things to my knowledge, can you help me a little bit on this please? I have updated the question with my codes. – sorry_I_wont Jan 13 '16 at 21:48
  • I have defined my own updateUI method that takes a MyNetwork variable and updates the UI...there are so many textViews that need to get updated, so it isn't possible( or good desgin)to pass them all to onPostExecute (check my code above? I shortened the updateUI method by deleting textviews from my original code) Do you also happen to know the answers to the 2 questions I asked? – sorry_I_wont Jan 13 '16 at 22:23
  • View related code must run in `onPostExecute`, for your other question check this http://stackoverflow.com/a/6207519/1880431 and yes call it in mainactivity – meda Jan 14 '16 at 16:22
  • But it IS being executed onPostExecute, I just put them all in one function(updateUI) so it would be a better/readable code!! are you saying all View widgets should be "directly" called in onPostExecute? – sorry_I_wont Jan 15 '16 at 06:50