sab215
sab215

Reputation: 11

Android Activity UI Performance (AsyncTask while-loop)

How can I make this more efficient, at the moment it hangs the activity, giving the following information in logcat every time the while-loop completes I assume:

I/Choreographer: Skipped 55 frames!  The application may be doing too much work on its
main thread.

Basically on a while-loop it reads a string variable, modifies and splits the string into parts which are then multiplied then divided, these final values are picked up by an interface which changes the custom UI element in the activity.

This seems too heavy on the main UI thread, I was under the impression that handler.post alleviates some of this by adding to the message queue however there are skipped frames.

I've tried to convert this code into an AsyncTask however I don't understand how this code can be converted to work in AsyncTask.


EDIT: AsyncTask custom class replacing old Thread while-loop.

(Old code for reference: http://pastebin.com/Dek6uQTE)

I'm still unsure how this fits in with AsyncTask, I have added the heavy code within the doInBackground() method however readBuf.replace and readBuf.split cannot be resolved. I thought to put the end changed in onProgressUpdate() as opposed to onPostExecute() as this would keep the UI elements updated automatically.

private class PostTask extends AsyncTask<Void, Void, Void> {

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        readBuf = ((MyApplication) getApplication()).getReadBuf();
    }

    @Override
    protected Void doInBackground(Void... readBuf) {
        while (readBuf.length > 4) {
            readBuf.replace("V", "");
            String[] parts = readBuf.split(",");
            String part1 = parts[0];
            String part2 = parts[1];
            speed1 = Float.parseFloat(part1);
            speed2 = Float.parseFloat(part2);
            finalspeed1 = (speed1 * 102) / div1;
            finalspeed2 = (speed2 * 602) / div1;
            publishProgress();
        }
    }

    @Override
    protected void onProgressUpdate(Void... values) {
        super.onProgressUpdate(values);
        speedometer.onSpeedChanged(speedometer.getCurrentSpeed() - speedcur1);
        speedometer.onSpeedChanged(speedometer.getCurrentSpeed() + finalspeed1);
        speedometer1.onSpeedChanged(speedometer.getCurrentSpeed() - speedcur2);
        speedometer1.onSpeedChanged(speedometer1.getCurrentSpeed() + finalspeed2);
    }

    @Override
    protected void onPostExecute(Void result) {
        super.onPostExecute(result);
    }
}

Upvotes: 1

Views: 255

Answers (1)

Larry Schiefer
Larry Schiefer

Reputation: 15775

You're starting a new thread which is actually just posting a new Runnable to the UI thread (handler is created on the UI thread), so it's not being done in the background. Here are a few tips to help with this:

  • If you are going to use a background thread to do the "work", then don't post a Runnable which is performing work to the handler, just post the result and update your UI accordingly.
  • Don't call findViewById() in a loop or any time after creation, if possible. Get a reference to the UI element and stash it off. This method is expensive as it does a search through your view hierarchy for the matching ID.
  • If you are going to use an AsyncTask just move the "work" part of your Runnable to the doInBackground() method and your UI updates into the onPostExecute() method.
  • Whether using a custom background Thread or AsyncTask, be sure to shutdown/cancel the work when your Activity leaves the run state, otherwise you will encounter problems as these components are not lifecycle aware.
  • It's not clear where readBuf is actually pulling data from, so this may also need some work. If this is real-time data coming from some other source, then you may need to have the custom Thread loop with a small yield. If using an AsyncTask, you'll have to create a new one each time as they are one-shot operations and not intended to be used as a long running background thread.

This article on AsyncTask has more details about how it works and pitfalls.

Upvotes: 1

Related Questions