Android Thread.sleep() in AsyncTask freeze UI

Evgeny E picture Evgeny E · May 15, 2013 · Viewed 7.2k times · Source

i'm tried many suggestions but nothing works! When i call Thread.sleep() in background thread, main thread also freezes for this time (Animation frame drop) :(

Version 1:

public void UpdateChannels(final ArrayList<Channel> channels)
{
    new AsyncTask<ArrayList<Channel>, Object[], Void>()
    {
        @Override
        protected Void doInBackground(ArrayList<Channel>... arrayLists)
        {
            for(Channel channel : arrayLists[0])
            {
                Integer chid = new Integer(channel.arfcn);
                ChannelRect channelRect = Channels.get(chid);
                publishProgress(new Object[] {channelRect, channel.dBm});

                try
                {
                    Thread.sleep(1000);
                } catch (InterruptedException e)
                {
                    e.printStackTrace();
                }
            }
            return null;
        }

        @Override
        protected void onProgressUpdate(Object[]... values)
        {
            ChannelRect channelRect = (ChannelRect) values[0][0];
            int value = (Integer)values[0][1];
            channelRect.setValue(value);
            channelRect.Animate();
        }
    }.execute(channels);
}

Version 2:

 public void UpdateChannels(final ArrayList<Channel> channels)
{
    new Thread(new Runnable()
    {
        @Override
        public void run()
        {
            for(final Channel channel : channels)
            {
                int chid = new Integer(channel.arfcn);
                final ChannelRect channelRect = Channels.get(chid);
                if(channelRect != null)
                {
                    CurrentActivity.runOnUiThread(new Runnable()
                    {
                        @Override
                        public void run()
                        {
                            channelRect.setValue(channel.dBm);
                            channelRect.Animate();
                        }
                    });
                    try
                    {
                        Thread.sleep(500);
                    } catch (InterruptedException e)
                    {
                        e.printStackTrace();
                    }
                }
            }
        }
    }).start();
}

And i tried same thing with post and Handler. Same thing :( When Thread.sleep(500) arrives animation freezes :(

What i'm doing wrong?

UPDATE 1

Found heavy place that slows UI thread:

I have horizontal LinearLayout that stores 175 ChannelRect views. When i call animate (that starts AlphaAnimation all okay, but when i setValue() to ChannelRect it must change his size:

public void setValue(int value)
{
    _value = value;
    setOpacity((byte)255);
    CurrentLayoutParams.height = (int)((-110 - value) * ycoeff * -1);
    requestLayout();
}

This is slow downs main UI thread. Why? setValue affects only one view in this LinearLayout not all... p.s. removing requestLayot() line remove slowdowns but ChannelRect size not changes :(

Answer

Evgeny E picture Evgeny E · May 15, 2013

The reason why animation freezes it's a requestLayout() in ChannelRect. Main LinearLayout that contains many (175+) custom views trying to redraw every children on requestLayout() called from updated child.

I'm changed my ChannelRect for drawing rectangle inside view and now calling Invalidate() instead requestLayout():

public void setValue(int value)
{
    _value = value;
    setOpacity((byte)255);
    invalidate();
}

@Override
protected void onDraw(Canvas canvas)
{
    canvas.drawRect(0,getHeight() - (int)((-110 - _value) * ycoeff * -1),size,getHeight(), pnt);
}