5

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 :(

Evgeny E
  • 145
  • 2
  • 11
  • the issue is not related with this code – Blackbelt May 15 '13 at 12:25
  • there is no heavy code in channelRect.setValue(value) or in channelRect.Animate() – Evgeny E May 15 '13 at 12:29
  • I never said it was there. – Blackbelt May 15 '13 at 12:30
  • i tried to remove any heavy code, there is no any work in activity, and i tried change sleep time and animation freezes time is similar thread.sleep time...same code in C# is working correctly – Evgeny E May 15 '13 at 12:37
  • 1
    Thread.sleep will pause the current thread for the specifcied time, if the thread is responsible for updating the animation, then the animation will be jerky. For example, the AsyncTask will only publishProgress every 1 second - which means you'll only get an animation frame rate of 1 fps. During this wait time, the UI Thread is probably still responsive. – FunkTheMonk May 15 '13 at 13:04
  • do you fix your issue? – Blackbelt May 15 '13 at 13:05
  • Your animation depends on the value that you are getting from your background thread and your interrupting it. So it's obvious that the animation gets choppy. – Sam R. May 15 '13 at 13:13
  • wrong, animation not getting background thread values – Evgeny E May 15 '13 at 13:16
  • `channelRect.setValue(value);` what is this then? It waits until background thread publishes the result and then you call `channelRect.Animate();` in your first sample. – Sam R. May 15 '13 at 13:19
  • i found source of lags, refresh my post – Evgeny E May 15 '13 at 13:22
  • Try removing `requestLayout();` to see if it lags again. Of course your layout will not be updated but do it just for test. – Sam R. May 15 '13 at 13:25
  • Removed and lags disappears. i think this is because requestLayout() invalidates full layout and redraws every view in layout.. – Evgeny E May 15 '13 at 13:28
  • `Not requestLayout() nor forceLayout() can actually make the UI refresh immediately, they will both schedule a layout request in the thread loop` from [here](http://stackoverflow.com/a/5430802/1693859) – Sam R. May 15 '13 at 13:29
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/30001/discussion-between-evgeny-e-and-sam-rad) – Evgeny E May 15 '13 at 13:35

1 Answers1

3

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);
}
Evgeny E
  • 145
  • 2
  • 11