Sunday, August 29, 2010

Best of this Week Summary 23 August - 29 August 2010

Wednesday, August 25, 2010

Endless flashing TextView animation in Android

A little while ago I needed a flashing text in Android.


Pretty easy you'd think: stick two animations in an AnimationSet, set the repeatMode to Animation.RESTART and repeatCount to Animation.INFITITE like this:

XML


<set xmlns:android="http://schemas.android.com/apk/res/android"
<alpha
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromAlpha="0.0"
    android:toAlpha="1.0"
    android:duration="1000"
/>
<alpha
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromAlpha="0.9"
    android:toAlpha="0.0"
    android:duration="1000"
    android:startOffset="1000"
/>
</set>



Activity code

AnimationSet c = (AnimationSet) AnimationUtils.loadAnimation(this, R.anim.flash);
c.setRepeatMode(Animation.RESTART);
c.setRepeatCount(Animation.INFINITE);
TextView tv = (TextView) findViewById(R.id.flashingTextView);
tv.clearAnimation();
tv.startAnimation(c);



and you're done.
But no! It only runs one time, or 1.5 times or whatever; definitely not endlessly.

This pretty basic requirement of looping a set of animations indefinitely is apparently a known bug. I haven't been able to find out if it's still an outstanding issue today (August 2010) but unless I implemented it incorrectly, it is definitely present in SDK 1.6.
Based on the answers in that thread and the example code here, I came up with the following solution:

XML
A fadein.xml and a fadeout.xml. See the end of this post for the complete code.

Activity code


    // Get ref to what we're going to animate (fade-in and fade-out indefinitely)
    tv = (TextView) findViewById(R.id.flashingTextView);

    // Setup fadein/out animations
   fadeIn = AnimationUtils.loadAnimation(this, R.anim.fadein);
   fadeIn.setAnimationListener( myFadeInAnimationListener );
   fadeOut = AnimationUtils.loadAnimation(this, R.anim.fadeout);
   fadeOut.setAnimationListener( myFadeOutAnimationListener );
   
   // And start with the fade in
   launchInAnimation();

    public void launchInAnimation() {
       tv.startAnimation(fadeIn);
    }    

    public void launchOutAnimation() {
       // Launch the second animation :
       tv = (TextView) findViewById(R.id.flashingTextView);
       tv.startAnimation(fadeOut);
    }    
    



Two listeners which start the other animation at the end of an animation:

    private class LocalFadeInAnimationListener implements AnimationListener {
       public void onAnimationEnd(Animation animation) {
           tv.post(mLaunchFadeOutAnimation);
        }
       public void onAnimationRepeat(Animation animation) {
       }
       public void onAnimationStart(Animation animation) {
       }
    };
    
    private class LocalFadeOutAnimationListener implements AnimationListener {
       public void onAnimationEnd(Animation animation) {
           tv.post(mLaunchFadeInAnimation);
      }
       public void onAnimationRepeat(Animation animation) {
      }
      public void onAnimationStart(Animation animation) {
      }
    };
    
    private LocalFadeInAnimationListener myFadeInAnimationListener = new LocalFadeInAnimationListener();
    private LocalFadeOutAnimationListener myFadeOutAnimationListener = new LocalFadeOutAnimationListener();




Runnables that do the fading

    private Runnable mLaunchFadeOutAnimation = new Runnable() {
       public void run() {
            launchOutAnimation();
       }
    };    
    
    private Runnable mLaunchFadeInAnimation = new Runnable() {
       public void run() {
        launchInAnimation();
       }
    };    



Note that I improved efficiency of the mentioned example code by only setting the animations one time and getting the TextView to animate only once.

That's it!

Note: in the logcat I do get these messages (2-3 times in about 5 minutes):


08-22 15:33:28.078: WARN/SurfaceComposerClient(252): lock_layer timed out (is the CPU pegged?) layer=0, lcblk=0x41048020, 
state=00000002 (was 00000043)
08-22 15:33:28.078: WARN/SurfaceComposerClient(252): lock_layer() timed out but didn't appear to need to be locked and 
we recovered (layer=0, lcblk=0x41048020, state=00000002)



Pretty strange, the CPU doesn't seem to be pegged... It says it recovers, but I guess the warning is there for a reason. Can the code be modified to avoid these warnings?
It might be a platform bug. Indeed I do see it appear in 1.6 but not in 2.1.

Full code (tested on 1.6) can be downloaded here.

Sunday, August 22, 2010

Best of this Week Summary 16 August - 22 August 2010

  • Great performance analysis (PDF) between Java IO and Java NIO by Google engineer Paul Tyma. Java IO is performing about 25% better.

  • Of course I have to mention Oracle's Java lawsuit against Google. Several viewpoints can be found here (more on the profit/free markets) and here (more elaborate and technical details) and here (Android == Java?).

  • A short comparison between Spring Web Services and Apache CXF.

  • Several short HTML5 tutorials by Bob Leah from IBM collected at one place.

  • Five things you might not know about .jar files.


Sunday, August 15, 2010

Best of this Week Summary 9 August - 15 August 2010

Sunday, August 8, 2010

Best of this Week Summary 2 August - 8 August 2010

Sunday, August 1, 2010

Best of this Week Summary 26 July - 1 August 2010

  • Pretty nasty, some application apparently depend on the the company name in the JDK! Including Eclipse, causing OutOfMemoryErrors since Oracle changed the name from 'Sun Microsystems, Inc' to 'Oracle'. Sounds like a magic constant somewhere... Though as it says here it had to be put in to work around another bug. Oracle rolled it back until JDK 7.

  • Evolutionary architecture and emergent design: Leveraging reusable code, Part 1 and Part 2.

  • A Spring MVC 3 Showcase, which should give you have a good idea of what the technology can do.It includes a sample project, along with a supporting slide presentation and screencast. After digging in, you should have a good understanding of what Spring MVC can do and get a feel for how easy it is to use.

  • Some random Android tips/lessons learned.

  • Java Iterator Quiz time!