tag:blogger.com,1999:blog-68435668306712773532024-03-12T19:48:12.363-07:00Codedependent<i>Graphics geek, performance pusher, animation animal</i>
<p><i>All content on this blog, unless marked otherwise, is original and is copyright © Chet Haase 2006-2015, all rights reserved.</i></p>Chet Haasehttp://www.blogger.com/profile/03250991041464602854noreply@blogger.comBlogger205125tag:blogger.com,1999:blog-6843566830671277353.post-35793028370390353112016-10-12T06:17:00.000-07:002016-10-12T06:17:02.925-07:00Droidcon London<div class="separator" style="clear: both; text-align: center;">
<a href="https://res.cloudinary.com/skillsmatter/image/upload/v1476268255/chet_square_lkik3v.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="200" src="https://res.cloudinary.com/skillsmatter/image/upload/v1476268255/chet_square_lkik3v.jpg" width="200" /></a></div>
<div style="background-color: white; color: #222222; font-family: arial, sans-serif; font-size: 12.8px;">
Join me and many other developers at <a href="http://uk.droidcon.com/">Droidcon London</a> at the end of October.</div>
<div style="background-color: white; color: #222222; font-family: arial, sans-serif; font-size: 12.8px;">
<br /></div>
<div style="background-color: white; color: #222222; font-family: arial, sans-serif; font-size: 12.8px;">
"Why Droidcon London?," you ask? Great question, thanks for asking! The answer is simple. But because I wanted to write more than six sentences to justify taking up your time reading this, I'm going to take longer to explain.</div>
<div style="background-color: white; color: #222222; font-family: arial, sans-serif; font-size: 12.8px;">
<br /></div>
<div style="background-color: white; color: #222222; font-family: arial, sans-serif; font-size: 12.8px;">
For one thing, there will be developers. Everywhere. Hanging from the rooftop, dangling from the balcony, occupying every seat - nothing but developers, developers, developers. None of these business-blogger types, no management consultants (well, <a class="m_1940105320290227177gmail-cremed m_1940105320290227177cremed cremed" data-saferedirecturl="https://www.google.com/url?hl=en&q=https://skillsmatter.com/skillscasts/6669-keynote-managing-expectations-a-manager-s-guide-for-managing-to-manage-unmanageable-teams-manageably&source=gmail&ust=1476364392407000&usg=AFQjCNGYs2X615QWfGKiUuvf4jNXtv3FOA" href="https://skillsmatter.com/skillscasts/6669-keynote-managing-expectations-a-manager-s-guide-for-managing-to-manage-unmanageable-teams-manageably" style="color: #1155cc;" target="_blank">very few anyway</a>) peddling their wares; just developers. So the people you talk to are exactly the people you want to connect with; other programmers learning the same stuff to solve the same problems that you have.</div>
<div style="background-color: white; color: #222222; font-family: arial, sans-serif; font-size: 12.8px;">
<br /></div>
<div style="background-color: white; color: #222222; font-family: arial, sans-serif; font-size: 12.8px;">
Also, there are always great technical talks. Developers aren't just in the seats and hanging from the fluorescents; they're up on stage talking about the stuff they know. In many conferences, the people on stage are the people that are carefully prepped to deliver on-message talks about products. But Droidcon is one of those awesome conferences that's all geek. The only difference between the presenters and the audience is that one of them has the mic (and the slides and demos ready to go). So there's great stuff to learn and great developers to learn from.</div>
<div style="background-color: white; color: #222222; font-family: arial, sans-serif; font-size: 12.8px;">
<br /></div>
<div style="background-color: white; color: #222222; font-family: arial, sans-serif; font-size: 12.8px;">
Finally, and I think this is the essence of the 'simple' answer that I wanted to give originally: it's the weather. It has been my experience that London has the most consistent weather of any place I've been. No matter when I arrive and how long I stay, the weather is always predictably gray, moist, cool, and somewhat dismal. Surely you get tired of the perfect weather where you are. I mean, how many sunny days in a row can you take before you just want to burst out in song? And who can get anything done in the office with happy people skipping around singing and smiling all the time? No, Droidcon London offers exactly the kind of weather that developers need to buckle down and Get Things Done, because, well, there aren't really any better options.</div>
<div style="background-color: white; color: #222222; font-family: arial, sans-serif; font-size: 12.8px;">
<br /></div>
<div style="background-color: white; color: #222222; font-family: arial, sans-serif; font-size: 12.8px;">
<a href="http://uk.droidcon.com/">Droidcon London</a>: It's not whether you will enjoy it, but rather weather you will enjoy.</div>
Chet Haasehttp://www.blogger.com/profile/03250991041464602854noreply@blogger.com0tag:blogger.com,1999:blog-6843566830671277353.post-4652575584293054382015-10-29T09:45:00.001-07:002020-11-18T17:22:09.647-08:00Measuring Activity Startup TimeIn recent talks I've given, as well as the <a href="https://medium.com/google-developers/developing-for-android-introduction-5345b451567c">Developing for Android</a> series, I talk about the need to launch quickly, and about how to ensure that you're testing the right launch speed (cold start, like after reboot and (mostly) after killing a task, vs. warm start, which is way faster because the activity just has to be brought to the foreground).<br />
<br />
Then someone asked me, quite reasonably, "So how do I get my app's launch time?"<br />
<br />
Then I paused and wondered the same thing...<br />
<br />
Whenever I've done this kind of benchmarking on framework code, I've had the ability to instrument exactly the bits I needed to. But how can non-framework developers get the information they need from just running the normal build?<br />
<br />
Fortunately, this information exists, and has since API 19. So if you're running on any release later than 4.4 (Kitkat), you should be set.<br />
<br />
All you have to do is launch your activity and look in logcat for something like this:<br />
<div class="p1">
<span class="s1"><br />
</span></div>
<div class="p1">
<pre><span class="s1">ActivityManager: Displayed com.android.myexample/.StartupTiming: +768ms</span></pre>
</div>
<div class="p1"><span class="s1"><i>Update 11/18/20: This log is now issued by ActivityTaskManager, not ActivityManager]</i></span></div><div class="p1"><br /></div><div class="p1">This information is output whenever an activity window is first drawn, after it goes through all of the startup stuff. This time includes the entire time that it took to launch the process, until the application ran layout and drew for the first time. This is basically the main information you need. It doesn't include the amount of time it took between the user clicking your app icon and the system getting ready to launch your activity, which is fine, because you cannot (as an app developer) affect that time, so there's no need to measure it. Instead, it includes all of the time it took to load your code, initialize your classes that are used at start time, run layout, and draw your app that first time. All of which is really what you want to measure, because that's what you can and should try to optimize.</div>
<div class="p1">
<span class="s1"><br />
</span></div>
<div class="p1">
<span class="s1">There's an additional option to be aware of. The 'Displayed' time is automatically reported, to give you a quick measure of how long that initial launch took. But what if you are also loading in some other content asynchronously and want to know how long it took for everything to be loaded, drawn, and ready to go? In that case, you'll want to additionally call <code>Activity.reportFullyDrawn()</code>, which will then report, in the log, the time between that initial apk start (the same time as that used for the Displayed time) and the time when you call the onReportFullyDrawn() method. This secondary time is a superset of the initial one (assuming you call it <i>after</i> the initial launch time, which is preferred), giving you the additional information about how long it took to do everything, including the follow-on work after the app was first displayed.</span></div>
<div class="p1">
<span class="s1"><br />
</span></div>
<div class="p1">
<span class="s1">There is another way of measuring startup time which is worth mentioning for completeness, especially since it uses my favorite device tool, screenrecord. This technique involves recording the entire experience of tapping on your app's icon to launch it and waiting until your app window is up and ready to go.</span><br />
<span class="s1"><br />
</span> <span class="s1">First, start screenrecord with the --bugreport option (which adds timestamps to the frames - this was a feature added in L. I think):</span><br />
<pre><span class="s1">$ adb shell screenrecord --bugreport /sdcard/launch.mp4</span></pre>
<span class="s1"><br />
</span> <span class="s1">Then tap your app icon, wait until your app is displayed, ctrl-C screenrecord, and pull the file up onto your host system with adb pull:</span><br />
<pre><span class="s1">$ adb pull /sdcard/launch.mp4</span></pre>
<span class="s1"><br />
</span> <span class="s1">Now you can open the resulting video and see what's happening when. To do this effectively, you'll need to have a video player that allows you to step frame-by-frame (Quicktime does this, not sure what the best player with this feature is on other OSs). Now step through the frames, noticing that there's a frame timestamp at the top of the video window.</span><br />
<span class="s1"><br />
</span> <span class="s1">Step forward until you see the app icon highlighted - this happens after the system has processed the click event on the icon and has started to launch the app. Note the frame time when this happened. Now frame-step forward until you see the first frame that your application's full UI begins to be visible. Depending on your launch experience (whether you have a starting window, a splash screen, etc.), the exact sequence of events and windows may vary. For a simple application you'll see the starting window come up first, then a cross-fade with the real UI in your application when it's ready. You want to note the first frame where you see any of the real UI content of your app. This happens when your app has finished layout and drawn itself, and is now ready to be shown. Note the time at this frame as well.</span><br />
<span class="s1"><br />
</span> <span class="s1">Now subtract the two times ((UI displayed) - (icon tapped)); this is the full time that it took for your app to go all the way from the initial user tap to being drawn and ready. It is a superset of the "Displayed" log described above, since it includes time before the process launches and after that first rendering (when the system starts the cross-fade animation), but it is at least something that you can use for comparison purposes with other launches after you make things faster and want to see how much better it is.</span><br />
<span class="s1"><br />
</span> <span class="s1">As with any performance testing, it's good to try to run your tests in similar situations multiple times (including making sure you're testing 'cold start' as noted above), as various things can happen to vary the results on any one run.</span><br />
<span class="s1"><br />
</span> <span class="s1">Now that you know how to figure out your launch times, whichever approach you use, go make it faster.</span><br />
<span class="s1">Please.</span></div>
Chet Haasehttp://www.blogger.com/profile/03250991041464602854noreply@blogger.com14tag:blogger.com,1999:blog-6843566830671277353.post-64984259746239124832015-06-09T09:02:00.000-07:002015-06-09T09:02:45.007-07:00Developing for AndroidA series of articles have been posted on the <a href="https://medium.com/google-developers">Google Developers</a> publication on medium.com that explain the constraints of mobile applications and a set of rules to keep in mind in order to develop good, well-performing Android applications.<br />
<br />
<a href="https://medium.com/google-developers/developing-for-android-introduction-5345b451567c">Introduction</a><br />
<a href="https://medium.com/google-developers/developing-for-android-i-understanding-the-mobile-context-fd2351b131f8">I: Understanding the Mobile Context</a><br />
<a href="https://medium.com/google-developers/developing-for-android-ii-bb9a51f8c8b9">II: Memory</a><br />
<a href="https://medium.com/google-developers/developing-for-android-iii-2efc140167fd">III: Performance</a><br />
<a href="https://medium.com/google-developers/developing-for-android-iv-e7dc4ce0a59">IV: Networking</a><br />
<a href="https://medium.com/google-developers/developing-for-android-v-f6b8038b42f5">V: Language & Libraries</a><br />
<a href="https://medium.com/google-developers/developing-for-android-vi-c0b1539f0e98">VI: Storage</a><br />
<a href="https://medium.com/google-developers/developing-for-android-vii-the-rules-framework-concerns-d0210e52eee3">VII: Framework</a><br />
<a href="https://medium.com/google-developers/developing-for-android-viii-e91ced595fac">VIII: The Rules: User Interface</a><br />
<a href="https://medium.com/google-developers/developing-for-android-ix-tools-375134af1098">IX: Tools</a>Chet Haasehttp://www.blogger.com/profile/03250991041464602854noreply@blogger.com2tag:blogger.com,1999:blog-6843566830671277353.post-42614924394178644532015-01-28T06:46:00.000-08:002015-01-28T13:17:26.424-08:00Android Development: Lotsa LinksThis is meant to be a living archive of Android presentations, articles, videos, whatever that I've presented, co-presented, written, been a witness to, or simply enjoyed and learned from. People ask for this stuff occasionally ("Where can I learn more about performance tuning on Android?" or "Where can I see more videos of Romain? He's so dreamy, with that almost-real French accent!"), so I thought it would be worth recording the links somewhere where I can add new ones over time as stuff comes online (and delete old ones as they become obsolete).<br />
<br />
I'll attempt to categorize things, but there is overlap on these topics. So the studious developer will, of course, watch and read everything. Twice.<br />
<br />
The links are presented in rough reverse-chronological order in each section. Some talks date way back to 2010, but they're still relevant today (the advantage of APIs that don't go away...).<br />
<br />
<h3>
General Android Development</h3>
<a href="http://androidbackstage.blogspot.com/">Android Developers Backstage</a> (Tor Norbye, Chet Haase, and guests)<br />
Tor and I interview other Android developers to talk about whatever it is that they do to help developers better understand how that stuff works.<br />
<br />
<h3>
Performance</h3>
<a href="https://parleys.com/play/5298f999e4b039ad2298c9e3">Android Performance Workshop, Part 1 (Devoxx 2013)</a> (Romain Guy & Chet Haase)<br />
This presentation is all about memory on Android: how the system works, things to think about to avoid garbage collection, and tools to use to help detect and debug problems.<br />
<br />
<a href="https://parleys.com/play/5298fafae4b039ad2298c9e5">Android Performance Workshop, Part 2 (Devoxx 2013)</a> (Romain Guy & Chet Haase)<br />
This talk covers some platform improvements, performance tips, and case studies of chasing and fixing performance issues.<br />
<br />
<a href="http://www.youtube.com/watch?v=vQZFaec9NpA">Android Graphics Performance (Google I/O 2013)</a> (Romain Guy & Chet Haase)<br />
More performance tips with demos of using the tools to find and fix problems.<br />
<br />
<a href="http://www.curious-creature.com/docs/android-performance-case-study-1.html">Android Performance Case Study</a> (Romain Guy)<br />
This article from Romain shows how he used many of Android's performance tools to debug performance issues like overdraw on a real world app.<br />
<br />
<a href="https://www.youtube.com/watch?v=Q8m9sHdyXnE">For Butter or Worse (Google I/O 2012)</a> (Romain Guy & Chet Haase)<br />
Romain and I discussed the graphics architecture of Android, along with various tips for achieving better performance.<br />
<br />
<a href="https://parleys.com/play/5148922b0364bc17fc56c9cd">Important Android Stuff, Part 2 (Devoxx 2012)</a> (Romain Guy & Chet Haase)<br />
More performance tips, more tools usage, more finding and fixing performance problems. More, more, more.<br />
<br />
<a href="https://parleys.com/play/514892290364bc17fc56c533">Android Tools (Devoxx 2011)</a> (Romain Guy & Chet Haase)<br />
A talk about some of the tools and techniques used for finding and fixing performance problems.<br />
<br />
<a href="https://www.youtube.com/playlist?list=PLWz5rJ2EKKc9CBxr3BVjPTPoDPLdPIFCE">Android Performance Patterns</a> (Colt McAnlis)<br />
This series of videos from Colt helps you understand how things work and what you need to know to write better performing Android apps.<br />
<br />
<h3>
Graphics & Animation</h3>
<a href="https://www.parleys.com/play/5471cb3ae4b0e15e672384be">Material Design (Devoxx 2014 keynote)</a> (Nick Butcher & Chet Haase)<br />
This talk is a combination of the design underpinnings of Material Design and some the platform API details for writing Material Design applications on both Android and Polymer.<br />
<br />
<a href="https://parleys.com/play/5471cc39e4b0e15e672384c1">Material Witness (Devoxx 2014)</a> (Romain Guy & Chet Haase)<br />
A talk about some of the Material Design APIs and techniques in the Android 5.0 Lollipop release, showing how they are used in a couple of sample applications.<br />
This talk overlaps with a talk by the same name at Google I/O 2014, but this version is updated to the final APIs (the Google I/O talk was based on the APIs in the L Developer Preview release).<br />
<br />
<a href="https://www.youtube.com/watch?v=lSH9aKXjgt8">Material Science (Google I/O 2014)</a> (Adam Powell & Chet Haase)<br />
This is a talk on writing Material Design applications. Some of the API details have changed since this presentation, since it was based on the L Developer Preview release, but the underlying ideas of developing for Material Design is the same.<br />
<div>
<br /></div>
<div>
<a href="https://parleys.com/play/5148922b0364bc17fc56c9cb/">Important Android Stuff, Part 1 (Devoxx 2012)</a> (Romain Guy & Chet Haase)<br />
An overview of the Animation APIs, both pre-3.0 (the android.view.animation classes) and post-3.0 (the android.animation classes, Object Animator, etc.).<br />
<br />
<a href="http://graphics-geek.blogspot.com/2012/01/curved-motion-in-android.html">Curved Motion in Android</a> (Chet Haase)<br />
New APIs in Android 5.0 Lollipop make this much easier (and built into the platform), but this article explains how to use ObjectAnimator and TypeEvaluator to make your animations curve on earlier releases.</div>
<div>
<br /></div>
<a href="https://parleys.com/play/514892280364bc17fc56c05a/">Android Graphics and Animation (Devoxx 2010)</a> (Romain Guy & Chet Haase)<br />
Romain and I talk about the general process of rendering Views on Android, graphics APIs for achieving various graphical effects, and the pre-3.0 Animation APIs.<br />
<br />
<a href="https://parleys.com/play/514892280364bc17fc56c0e2/">Dive Into Android, Part 1 (Devoxx 2010)</a> (Romain Guy)<br />
Romain talks about the broader concepts of layout on Android, and the various built-in layout classes to use. He then steps through an example of creating a simple custom layout, to explain the process of measurement and layout that such a subclass must handle.<br />
<br />
<a href="https://parleys.com/play/514892280364bc17fc56c0e9/">Dive Into Android, Part 2 (Devoxx 2010)</a> (Romain Guy & Chet Haase)<br />
Tips and techniques for creating graphical effects in Android applications.<br />
<br />
<a href="https://www.youtube.com/watch?v=NYtB6mlu7vA">Writing Custom Views for Android (Google I/O 2013)</a> (Romain Guy & Adam Powell)<br />
Romain and Adam Powell talk about custom views.<br />
<br />
<a href="https://parleys.com/play/514892290364bc17fc56c4dc">Stick GUIs</a> (Romain Guy & Chet Haase)<br />
Romain and I talk about various rich graphical effects for Android applications.<br />
<br />
<a href="https://medium.com/@romainguy/androids-font-renderer-c368bbde87d9">Android's Font Renderer</a> (Romain Guy)<br />
Romain's article about how Android renders text using the GPU.<br />
<br />
<a href="https://www.youtube.com/playlist?list=PLWz5rJ2EKKc_XOgcRukSoKKjewFJZrKV0">DevBytes</a> (Chet Haase & many others)<br />
It's definitely worth checking out the DevBytes playlist. The content there is diverse, but it's clear to tell from the title whether it's something that you're interested in, and they all provide a quick deep dive into their topic of choice. There are a bunch of videos specific to animation and graphical effects, but there are many more videos on a wide range of Android topics.<br />
<br />
<br />Chet Haasehttp://www.blogger.com/profile/03250991041464602854noreply@blogger.com4tag:blogger.com,1999:blog-6843566830671277353.post-63099925476785143952014-09-24T06:37:00.002-07:002014-10-05T15:31:43.928-07:00Devoxx 2013 PresentationsAll of the talks from <a href="https://parleys.com/channel/528b321de4b054cd7d2ef448/presentations?sort=date&state=public">Devoxx 2013</a> are now freely available on the <a href="http://parleys.com/">parleys.com</a> website. This includes all of the talks that I did with Romain Guy on Android:<br />
<a href="https://parleys.com/play/529474eee4b0524648d3aeab/chapter0/about">Filthy Rich [Android] Clients</a><br />
<a href="https://parleys.com/play/528ee9fbe4b084eb60ac7929/chapter0/about">What's New in Android</a><br />
<a href="https://parleys.com/play/5298f999e4b039ad2298c9e3/chapter0/about">Android Performance Workshop Part 1</a><br />
<a href="https://parleys.com/play/5298fafae4b039ad2298c9e5/chapter0/about">Android Performance Workshop Part 2</a><br />
<br />
There's also an <a href="https://parleys.com/play/5294ad75e4b0e619540cc335/chapter0/about">interview</a> about the new features in KitKat.<br />
<br />
Then there's this somewhat less relevant <a href="https://parleys.com/play/529cb762e4b039ad2298ca27/chapter0/about">Patterns, Shmatterns</a> talk I did about software design patterns.<br />
<br />
All of the slides from the Android talks are posted <a href="http://www.curious-creature.org/2013/11/17/devoxx-2013-presentations/">on Romain's blog</a>.Chet Haasehttp://www.blogger.com/profile/03250991041464602854noreply@blogger.com0tag:blogger.com,1999:blog-6843566830671277353.post-4808155564557503482014-07-05T12:35:00.001-07:002014-07-05T12:35:14.329-07:00Presenting Presenting: Tips and Thoughts on Preparing and Giving Engaging PresentationsI've written this article about preparing and giving presentations:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://medium.com/@chethaase/17233fa13aa5" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgC1qOyQQS0aP_1irvNeiooff_LH3yTDYVJkw-S1_LLZ3oxwtTyX97O9SDINdux_4RwuuED6xtQEH08xKpHvdBqxGa_4_TjSlSFQ5iWqYKLQbx1Ntufy948TeT6oAz2qDNGO3RXLfvsUXE/s1600/Screen+Shot+2014-07-05+at+12.30.56+PM.png" height="287" width="400" /></a></div>
<br />Chet Haasehttp://www.blogger.com/profile/03250991041464602854noreply@blogger.com2tag:blogger.com,1999:blog-6843566830671277353.post-62274386544512943962014-06-27T10:08:00.000-07:002014-06-27T10:08:24.742-07:00Google I/O 2014: RehashAll of the videos have been posted from the various sessions I was in this year. Here they are, along with links to the slides.<br />
<br />
<h3>
What's new in Android</h3>
A presentation with <a class="g-profile" href="https://plus.google.com/114592751246503219483" target="_blank">+Dan Sandler</a> that provides a quick overview of some of the larger features and new APIs in the L Developer Preview release and other new bits in the recent Androidosphere. There's also a really good deep-dive into Notifications, since Dan's the non-local expert on the subject.<br />
<br />
<div style="text-align: center;">
<iframe allowfullscreen="" frameborder="0" height="315" src="//www.youtube.com/embed/3TtVsy98ces" width="560"></iframe><br /></div>
<br />
<a href="https://sites.google.com/site/androidcontentfromchet/downloads/Whats%20New%20in%20Android.pdf">Slides (PDF)</a><br />
<br />
<hr />
<h3>
Material science</h3>
This session, presented with <a class="g-profile" href="https://plus.google.com/107708120842840792570" target="_blank">+Adam Powell</a>, provides an overview of the engineering side of the Material design system. Many of the other sessions at Google I/O this year discussed the design side; this presentation covers the technical details of the APIs and the capabilities exposed by the framework for Android developers.<br />
<br />
<div style="text-align: center;">
<iframe allowfullscreen="" frameborder="0" height="315" src="//www.youtube.com/embed/lSH9aKXjgt8" width="560"></iframe><br /></div>
<br />
<a href="https://sites.google.com/site/androidcontentfromchet/downloads/MaterialScience.pdf">Slides (PDF)</a><br />
<br />
<hr />
<h3>
Material witness</h3>
I was happy to be joined once again by former Android developer and UI Toolkit team lead <a class="g-profile" href="https://plus.google.com/109538161516040592207" target="_blank">+Romain Guy</a> for this talk on some of the new Material design elements in the L Developer Preview release. The idea behind this talk was to go a bit deeper into using and explaining the new APIs, as well as explaining how some of the features, like realtime soft shadows, work.<br />
<br />
<div style="text-align: center;">
<iframe allowfullscreen="" frameborder="0" height="315" src="//www.youtube.com/embed/97SWYiRtF0Y" width="560"></iframe><br /></div>
<br />
For slides as well as demo code, check out <a href="http://www.curious-creature.org/2014/06/26/google-io-2014-slides-and-demo/">Romain's blog at curious-creature.org</a>.<br />
<br />
<hr />
<h3>
Android fireside chat</h3>
This session, organized and moderated by <a class="g-profile" href="https://plus.google.com/111169963967137030210" target="_blank">+Reto Meier</a>, I found to be more interesting than other such panels I've seen. Often, these things tend to have a lot of awkward silences as the panelists try to figure out the most interesting way of saying "No comment" since there's a general policy on Android of not talking about future development plans. This time, there was a lot of discussion around how and why some parts of the system work, which I enjoyed as an audience member that just happened to be sitting somewhat closer to the panel.<br />
<br />
<div style="text-align: center;">
<iframe allowfullscreen="" frameborder="0" height="315" src="//www.youtube.com/embed/K3meJyiYWFw" width="560"></iframe></div>
Chet Haasehttp://www.blogger.com/profile/03250991041464602854noreply@blogger.com0tag:blogger.com,1999:blog-6843566830671277353.post-78958574518773453932014-03-07T18:14:00.000-08:002014-03-07T18:35:35.942-08:00Android Developers Backstage: The Podcast. Episode 5 and CountingIn an earnest attempt to reach more people (or perhaps a desperate attempt to build up a larger audience) I though it would be good to post this reference to the existing five (5) episodes of the podcast that <a href="http://google.com/+TorNorbye">Tor Norbye</a> and I have been working on for the past several weeks. And by "working on," I mean we get together every 2-4 weeks, sit down with someone interesting on one of the Android development teams and talk about technology and APIs that interest us, and then let someone else figure out the tedious details of actually recording and posting the results. So it's not really <i>work</i> as much as work-<i>related</i>.<br />
<br />
The goal of the podcast from the beginning was to have conversations with engineers and teams that listeners might not otherwise know and to talk about details of features and functionality of the Android platform that might not be obvious from simply reading the documentation. Because, hey, who reads the docs anyway, right?<br />
<br />
So far we've released five (5!) episodes, although there is a rumor that there is already a sixth (6th!) episode (<i>already recorded!)</i> that is being closely held onto until an undisclosed date <i>(soon!)</i> with a secret person <i>(<a href="http://google.com/+DanSandler">Dr. Daniel Sandler</a>!)</i> talking about a mysterious project on Android <i>(the System UI!)</i>, so who knows where things will go from here? <i>(Maybe to Fresno!)</i><br />
<br />
Since you're probably dying of too-much-text and too-few-links, here is the huge list of episodes so far:<br />
<br />
<a href="http://androidbackstage.blogspot.com/2013/11/android-developers-backstage-episode-1.html">Episode 1: KitKat</a> (with your hosts, <a href="https://plus.google.com/+ChetHaase/posts">Chet</a> and <a href="http://google.com/+TorNorbye">Tor</a>)<br />
<a href="http://androidbackstage.blogspot.com/2013/12/chet-haase-tor-norbye-are-joined-by.html">Episode 2: Storage</a> (Tor, Chet, and <a href="https://plus.google.com/+JeffSharkey">Jeff Sharkey</a>)<br />
<a href="http://androidbackstage.blogspot.com/2014/01/android-developers-backstage-ep-3.html">Episode 3: Security</a> (Chet, Tor, and <a href="https://plus.google.com/+AdrianLudwig/posts">Adrian Ludwig</a>)<br />
<a href="http://androidbackstage.blogspot.com/2014/02/tor-norbye-and-chet-haase-are-joined-by.html">Episode 4: Google Play Services</a> (Tor, Chet, and <a href="https://plus.google.com/109320716562117334675/posts">Jeff Hamilton</a>)<br />
<a href="http://androidbackstage.blogspot.com/2014/02/android-developers-backstage-episode-5.html">Episode 5: RenderScript</a> (Chet, Tor, and <a href="https://plus.google.com/115541647076262817681/posts">Tim Murray</a>)<br />
Episode 6: THERE IS NO EPISODE 6!!!!!! (yet)<br />
<br />
The feed itself is available through <a href="http://feeds.feedburner.com/blogspot/AndroidDevelopersBackstage">Feedburner</a>, and of course the podcast is also in <a href="https://itunes.apple.com/us/podcast/android-developers-backstage/id785545036?mt=2">iTunes</a> for those that live their audio lives there.<br />
<br />
By the way, if you have suggestions about teams, individuals, or technologies that <i>you</i> would like to hear more about, please leave a comment. We have a pretty much infinite list of people that we're going to try to get onto the show, but we're open to suggestions.<br />
<br />Chet Haasehttp://www.blogger.com/profile/03250991041464602854noreply@blogger.com0tag:blogger.com,1999:blog-6843566830671277353.post-62381424097179255792013-11-27T07:08:00.001-08:002013-12-02T13:48:35.547-08:00Android Developers Backstage: The PodcastAre there any geeks out there interested in new podcasts? What about podcasts about Android development?<br />
<br />
<a href="https://plus.google.com/+TorNorbye">Tor Norbye</a> and I are proud to announce a new podcast we've started called Android Developers Backstage. It's a podcast by and for Android programmers, featuring engineers on the Android team at Google talking about features, APIs, and technologies that we think are important for developers to know about. Or which we find interesting. Or which randomly happened to come up on the show.<br />
<br />
If your podcast client still has room and you have an extra half-hour (ish) every month (ish), then subscribe and tune in. You can find the podcast on <a href="http://feeds.feedburner.com/blogspot/AndroidDevelopersBackstage">Feedburner</a>. Just click on one of the various links on that page to add it to your podcast client of choice.<br />
<br />
The inaugural episode is about Android KitKat, with Tor and I talking about some of the new features in the latest release. In future episodes of the podcast, we'll interview other engineers on the team to deep-dive technologies they've worked on. Android development info, straight from the source.Chet Haasehttp://www.blogger.com/profile/03250991041464602854noreply@blogger.com1tag:blogger.com,1999:blog-6843566830671277353.post-54488114441821468442013-10-31T11:41:00.001-07:002013-10-31T11:41:28.634-07:00Android KitKat: Developer InfoWe just released Android KitKat and posted lots of information about it:<br />
<br />
Developer highlights: <a href="http://developer.android.com/about/versions/kitkat.html">http://developer.android.com/about/versions/kitkat.html</a><br />
<br />
Android Developers Blog: <a href="http://android-developers.blogspot.com/2013/10/android-44-kitkat-and-updated-developer.html">http://android-developers.blogspot.com/2013/10/android-44-kitkat-and-updated-developer.html</a><br />
<br />
Videos (an overview one plus lots of others that dive deeper into specific features): <a href="https://www.youtube.com/watch?v=sONcojECWXs&list=PLWz5rJ2EKKc-2quE-o0enpILZF3nBZg_K&index=1">https://www.youtube.com/watch?v=sONcojECWXs&list=PLWz5rJ2EKKc-2quE-o0enpILZF3nBZg_K&index=1</a><br />
<br />
I'll specifically call out the video on Transitions, which is something I recorded last week after finally finishing the feature. I hope that the API is another step toward making animations easier and more automatic in Android applications.<br />
<br />
<div style="text-align: center;">
<iframe allowfullscreen="" frameborder="0" height="315" src="//www.youtube.com/embed/S3H7nJ4QaD8?list=PLWz5rJ2EKKc-2quE-o0enpILZF3nBZg_K" width="560"></iframe></div>
Chet Haasehttp://www.blogger.com/profile/03250991041464602854noreply@blogger.com8tag:blogger.com,1999:blog-6843566830671277353.post-23919706312026888952013-09-12T08:56:00.000-07:002013-09-12T10:29:22.909-07:00Lazy ListsLet's talk about laziness. No, let's not just <i>talk</i> about being lazy - let's do something about it. Let's <i>be</i> lazy.<br />
<br />
There's a common pattern that I use in Android programming where I will create objects lazily, especially when these objects will not necessarily or frequently be needed at runtime. This is especially true for code that I write for the Android framework, where we like to be as lean as possible and leave more memory available for the system and the application.<br />
<br />
Often, these objects are collections. My personal favorite is <code>ArrayList</code> (ever since I moved on years ago from the original, but somewhat crusty, <code>Vector</code> class), although I am also known to use <code>Hashmap</code> for those key/value pair situations (especially after I got used to ActionScript's paradigm of everything-is-a-hashmap).<br />
<br />
Of course, you can't simply start poking into a lazily-created collection willy-nilly, unless you're a big fan of NullPointerExceptions. So you need to first check whether the thing is null, and then create it as necessary. Similarly, if you're removing an item from the collection, you might want to check if it's now empty and reset the field to <code>null</code> again.<br />
<br />
None of this is difficult... but it is tedious. And it tends to bloat the code that you have to read and write and maintain all over the place. And it's exactly the kind of thing that is easy to get wrong because your mind just blurs over the repeated pattern like it's yet another pile of dirty laundry next to the bed.<br />
<br />
So I wondered if there was a way I could encapsulate the behavior I wanted to make my laziness easier, simpler, and more readable. And it turns out there was such a way (or else this would be a very short article that would have ended right around... now).<br />
<br />
But first, let's look at the problem a bit more, to understand what we're trying to fix.<br />
<br />
I have a class called <code>LazyLists</code> with a couple of List fields and some methods for adding and removing items of various types. First, there are the fields:<br />
<br />
<pre>List<Integer> intList = null;
List<Float> floatList = null;
</pre>
<br />
Then there are add/remove fields for the int/float types I care about:<br />
<br />
<pre>public void addItem(int item) {
if (intList == null) {
intList = new ArrayList<integer>();
}
if (!intList.contains(item)) {
intList.add(item);
}
}
public void removeItem(int item) {
if (intList != null) {
intList.remove((Object) item);
if (intList.isEmpty()) {
intList = null;
}
}
}
public void addItem(float item) {
if (floatList == null) {
floatList = new ArrayList<float>();
}
if (!floatList.contains(item)) {
floatList.add(item);
}
}
public void removeItem(float item) {
if (floatList != null) {
floatList.remove(item);
if (floatList.isEmpty()) {
floatList = null;
}
}
}
</float></integer></pre>
<br />
There are a few things to notice about these methods:<br />
<ul>
<li>There's all of that boilerplate code I mentioned before that lazily creates and nulls out the appropriate list based on the state of the list at the time. This is what we'd like to clean up, since this code is repeated as many times as we have to access these list fields.</li>
<li>I run a uniqueness check in the <code>addItem()</code> methods because it suits me; I only want to add unique items, not the same items over and over. That's kind of a detail that's specific to my situation, but produces more boilerplate that I'd love to get rid of.</li>
<li>There an interesting nuance to the int variation of <code>removeItem()</code>. Do you see it? It's the cast to <code>Object</code> prior to removing the item from <code>intList</code>. This is because of the awkward crossover between primitive types (int, float, etc.) and Object types (Integer, Float, etc.) in Java. There are actually two <code>remove()</code> methods on List, one that takes an <code>int</code> and one that takes an <code>Integer</code>. The one that takes an <code>int</code> removes the item <i>at that index</i>, whereas the <code>Integer</code> variant removes <i>that item itself</i>. That's a pretty huge distinction. And maybe it's well-known to you if you've worked with Lists and ints, but I hit it when working on this example, and thought it was <code>int</code>eresting enough to call out.</li>
</ul>
Anyway, moving on.<br />
<br />
We can call the methods above and produce lists that dynamically change with the items that we add/remove. For example, this code creates the class, adds items to the two lists, and removes those items:<br />
<br />
<pre>LazyLists lists = new LazyLists();
lists.addItem(0);
lists.addItem(1f);
lists.removeItem(0);
lists.removeItem(1f);
</pre>
<br />
Adding a bit of tracing code gives us this output:<br />
<br />
<pre>starting lists = null, null
populated lists = [0], [1.0]
ending lists = null, null
</pre>
<br />
So there's not too much cruft above, but I figure the second time I'm repeating the same code, I should think about refactoring it in a way that avoids the repetition. And it's easy to imagine that there might be several places in real code that wants to add/remove items, or several different types going into several different types of collections. Then it's easy to see the little bits of repeated code above bloating into more than you might want to manage in the long haul.<br />
<br />
There are various ways that you could do this, depending on the collection(s) you want to support, the extra logic you'd like (like my requirement for uniqueness in the lists), and stylistic elements about static methods, etc. But here's what I wound up with:<br />
<br />
<pre>public class LazyListManager {
public static <t> List<t> add(List<t> list, T item) {
if (list == null) {
list = new ArrayList<t>();
list.add(item);
} else if (!list.contains(item)) {
list.add(item);
}
return list;
}
public static <t> List<t> remove(List<t> list, T item) {
if (list != null) {
list.remove(item);
if (list.isEmpty()) {
list = null;
}
}
return list;
}
}
</t></t></t></t></t></t></t></pre>
<br />
This simple class has two static methods on it to support adding and removing from an arbitrary List object. As needed, it will create a new List (actually, an ArrayList, but that's an implementation detail). It will check for uniqueness in the <code>add()</code> method, check for nullness in the <code>remove()</code> method, and null out an empty list in <code>remove()</code> as appropriate.<br />
<br />
There is an important piece here that makes this work - callers <i>must</i> supply their target list as both a parameter to the function <i>and as the recipient of the return value</i>; this is what makes it possible for these utility methods to allocate or null-out the list as appropriate (since they do not have access to the original list, but only have a reference to it).<br />
<br />
Given these two static utility methods, we can now write new <code>addItem()</code> and <code>removeItem()</code> methods that are a significantly better (you can't get less than one line of code, unless I missed that part in my CS education):<br />
<br />
<pre>public void addItemBetter(int item) {
intList = LazyListManager.add(intList, item);
}
public void removeItemBetter(int item) {
intList = LazyListManager.remove(intList, item);
}
public void addItemBetter(float item) {
floatList = LazyListManager.add(floatList, item);
}
public void removeItemBetter(float item) {
floatList = LazyListManager.remove(floatList, item);
}
</pre>
<br />
Calling these methods looks remarkably similar to what we saw before:<br />
<br />
<pre>lists.addItemBetter(0);
lists.addItemBetter(1f);
lists.removeItemBetter(0);
lists.removeItemBetter(1f);
</pre>
<br />
and results in exactly the same output (which shouldn't be a surprise. If the results were different, this approach wouldn't be a utility as much as a bug):<br />
<br />
<pre>starting lists = null, null
populated lists = [0], [1.0]
ending lists = null, null
populated lists = [0], [1.0]
ending lists = null, null
</pre>
<br />
The <code>LazyListManager</code> class has taken out all of the tedious boilerplate related to null checks, uniqueness, allocation, and nullification, and has left us with just one line of code to write whenever we want to add or remove items to/from one of our lists. That's just about the right amount of code for me to write without making a typo or a copy/paste error along the way.<br />
<br />
If this were public API, I could envision the manager class offering various different kinds of collections and options, or maybe wrapping more of the capabilities of collections classes (like isEmpty() or contains()). But for now, it's a nice little internal class that can help me simplify my code whenever I need to use this lazy-allocation pattern.<br />
<br />
All of the interesting code is inline above, but if you want the two source files, you can <a href="https://sites.google.com/site/androidcontentfromchet/downloads/LazyLists.zip">download them here</a>.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjxRmTZDwfuFI8JJ2KT0UEkHxgLJYMqppySQ6WymrTw_PUlKTKIgluNleuhaLEsDyU-eYyxDmUfYgG2kuDkRdpNm4n4645yN8aBdpdk_EsnSVlslK961ni2TjdxM4rYFwkjJD1yN0mF-ng/s1600/ProgrammerImagines.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjxRmTZDwfuFI8JJ2KT0UEkHxgLJYMqppySQ6WymrTw_PUlKTKIgluNleuhaLEsDyU-eYyxDmUfYgG2kuDkRdpNm4n4645yN8aBdpdk_EsnSVlslK961ni2TjdxM4rYFwkjJD1yN0mF-ng/s640/ProgrammerImagines.png" width="340" /></a></div>
<br />Chet Haasehttp://www.blogger.com/profile/03250991041464602854noreply@blogger.com5tag:blogger.com,1999:blog-6843566830671277353.post-59033125671652727582013-08-09T10:36:00.003-07:002013-08-09T10:36:40.546-07:00DevBytes: Cartoon Animation TechniquesThis time, we wrap up the series on cartoon animation techniques with a demo that shows a few of the techniques in the context of a larger application. Because it's nice to know how to write the code, but you might also be wondering why you might want to.<br />
<br />
For some real-world context, you could also check out games such as Candy Crush Saga (a horribly addictive game I've gotten sucked into that's less like casual gaming and more like casual crack). It uses a veritable plethora of cartoon animation techniques to keep the player engaged with the game and disengaged from their life.<br />
<br />
This and other cartoon animation techniques were discussed in the talk <a href="http://www.youtube.com/watch?v=ihzZrS69i_s">A Moving Experience</a> at Google I/O 2013<br />
<br />
Code: <a href="http://developer.android.com/shareables/devbytes/ToonGame.zip">http://developer.android.com/shareables/devbytes/ToonGame.zip</a><br />
<br />
YouTube: <a href="https://www.youtube.com/watch?v=8sG3bAPOhyw&list=PLWz5rJ2EKKc_XOgcRukSoKKjewFJZrKV0">https://www.youtube.com/watch?v=8sG3bAPOhyw&list=PLWz5rJ2EKKc_XOgcRukSoKKjewFJZrKV0</a><br />
<br />
<div style="text-align: center;">
<iframe allowfullscreen="" frameborder="0" height="315" src="//www.youtube.com/embed/8sG3bAPOhyw?list=PLWz5rJ2EKKc_XOgcRukSoKKjewFJZrKV0" width="560"></iframe></div>
Chet Haasehttp://www.blogger.com/profile/03250991041464602854noreply@blogger.com0tag:blogger.com,1999:blog-6843566830671277353.post-18049126749218232592013-08-02T07:54:00.001-07:002013-08-02T10:46:19.499-07:00DevBytes: Squash & StretchCartoon animation uses a technique called "squash & stretch" for achieving different effects of objects interacting with their environment.<br />
<br />
This episode shows how we can use similar techniques to get more organic and lively animations in user interfaces.<br />
<br />
This and other cartoon animation techniques were discussed in the talk <a href="http://www.youtube.com/watch?v=ihzZrS69i_s">A Moving Experience</a> at Google I/O 2013.<br />
<br />
Code: <a href="http://developer.android.com/shareables/devbytes/SquashAndStretch.zip">http://developer.android.com/shareables/devbytes/SquashAndStretch.zip</a><br />
<br />
YouTube: <a href="https://www.youtube.com/watch?v=wJL1oW6DlCc">https://www.youtube.com/watch?v=wJL1oW6DlCc</a><br />
<br />
<div style="text-align: center;">
<iframe allowfullscreen="" frameborder="0" height="315" src="//www.youtube.com/embed/wJL1oW6DlCc" width="560"></iframe><br />
<br />
<div style="text-align: left;">
Or, in illustrated form:</div>
<div style="text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-YH6oGdbJsPY/Ufvt5Z74YLI/AAAAAAAANLc/dOlGJKtUjwQ/s1600/CIMG0723-MOTION.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="http://2.bp.blogspot.com/-YH6oGdbJsPY/Ufvt5Z74YLI/AAAAAAAANLc/dOlGJKtUjwQ/s320/CIMG0723-MOTION.gif" width="320" /></a></div>
<br />
<br /></div>
Chet Haasehttp://www.blogger.com/profile/03250991041464602854noreply@blogger.com2tag:blogger.com,1999:blog-6843566830671277353.post-82076436163040972972013-07-26T11:07:00.000-07:002013-07-26T11:07:09.412-07:00DevBytes: Anticipation & Overshoot, Part 2Like my previous DevBytes episode, <a href="http://www.youtube.com/watch?v=uQ7PTe7QMQM&list=PLWz5rJ2EKKc_XOgcRukSoKKjewFJZrKV0">Anticipation and Overshoot, Part I</a>," this episode covers cartoon animation techniques for making UI elements more engaging and playful. The code in this episode shows how to change and animate how a button is drawn to make it seem more alive and organic.<br />
<br />
This and other cartoon animation techniques were discussed in the talk <a href="http://www.youtube.com/watch?v=ihzZrS69i_s">A Moving Experience</a> at Google I/O 2013.<br />
<br />
Code: <a href="http://developer.android.com/shareables/devbytes/Anticipation.zip">http://developer.android.com/shareables/devbytes/Anticipation.zip</a><br />
<br />
YouTube: <a href="https://www.youtube.com/watch?v=Z-XqlSwbCGU">DevBytes: Anticipation and Overshoot - Part 2</a><br />
<br />
<div style="text-align: center;">
<iframe allowfullscreen="" frameborder="0" height="315" src="//www.youtube.com/embed/Z-XqlSwbCGU" width="560"></iframe></div>
Chet Haasehttp://www.blogger.com/profile/03250991041464602854noreply@blogger.com1tag:blogger.com,1999:blog-6843566830671277353.post-45566116284871356502013-07-25T20:37:00.000-07:002013-07-26T07:11:11.871-07:00New in Android 4.3: ViewOverlaySince we just released Android 4.3 yesterday, I thought I'd wax poetic about one of the features I worked on in the release: Overlays.<br />
<br />
<div style="text-align: center;">
<i>Android devs</i></div>
<div style="text-align: center;">
<i>Come out to play:</i></div>
<div style="text-align: center;">
<i>Use the new</i></div>
<div style="text-align: center;">
<i>ViewOverlay.</i></div>
<div style="text-align: center;">
<br /></div>
There are many ways to get custom graphics (drawables) to appear in a view. You can set a background drawable if that's what you want, or you can use an ImageView, or you can create a custom View subclass and override onDraw(). Or if you want to draw them over the children in a layout, you can override the layout and override dispatchDraw() to draw them after all of the children (after a call to super.dispatchDraw()). But sometimes you just want something simpler: <a href="http://developer.android.com/reference/android/view/ViewOverlay.html">ViewOverlay</a>.<br />
<br />
Here's how it works:<br />
<br />
You call <a href="http://developer.android.com/reference/android/view/View.html#getOverlay()">View.getOverlay()</a>, which returns a ViewOverlay object. Then you call add(Drawable) on that overlay object... and that's it. You can also call remove(Drawable) to get rid of the drawable or clear() to get rid of everything in the overlay, but that's the entire API. The only other detail is that you need to set the bounds on your drawables (as you would if you were drawing them manually in onDraw()); the overlay doesn't do any positioning or sizing, it simply draws everything you tell it to, in the order in which the objects are added.<br />
<br />
Oh, and one other thing: you can also add View objects to an overlay if you get that overlay from a ViewGroup. That is, ViewGroup overrides getOverlay() to return a <a href="http://developer.android.com/reference/android/view/ViewGroupOverlay.html">ViewGroupOverlay</a>, which is a subclass of ViewOverlay that also deals with views in addition to drawables. Once again, the API is simple: there's an add(View) method and a remove(View) method. And once again, you are responsible for positioning/sizing the views where you want them in the overlay; the overlay does not do any layout.<br />
<br />
Essentially, the overlay is a container for drawables (and sometimes views) that is the exact size of its host view. It doesn't do layout; it just draws the stuff its told to, after it's drawn everything else in its host view (including any children of that host view, if the view is a ViewGroup).<br />
<br />
<b>Important caveat, especially with respect to ViewGroupOverlay</b>: The overlay is intended for temporary <i>display</i> of views, not for any long-term or functional use for views. In particular, the views there are not laid out by the container (as noted above) and do not participate in focus or input events. Overlays were created to be a visual-only mechanism, for things like transient animations. Think about things like fading out a view. This can be tricky in some situations where removing it immediately removes it from the view hierarchy and makes it tough to have it drawn while it's fading out. Now you can pop it into the overlay of its parent while it's going away.<br />
<br />
Here's another interesting thing to ponder: you can add drawables/graphics <i>anywhere</i> in the view hierarchy that makes sense for your situation. So, for example, if you wanted to fade out a view or some drawable while sliding it off the screen, or up-scaling it, outside of its parent container, this might normally be a problem because parent containers like to clip their children to their bounds by default. Now you can add the object into an overlay anywhere up the tree, to give you the flexibility to move/resize it as you see fit without worrying about the clipping constraints of that original parent.<br />
<br />
Anyway, I'm sure you can find interesting things to do with overlays. So go ahead!Chet Haasehttp://www.blogger.com/profile/03250991041464602854noreply@blogger.com19tag:blogger.com,1999:blog-6843566830671277353.post-41242605122093140902013-07-19T13:20:00.002-07:002013-07-19T13:20:23.150-07:00DevBytes: Anticipation and Overshoot, Part 1Some principles of cartoon animation can be used to provide more engaging and more interactive experiences in applications.<br />
<br />
This episode demonstrates principles of anticipation and overshoot with a simple button click, showing how to animate changes in the button's appearance to make it interact more playfully with the user.<br />
<br />
This and other cartoon animation techniques were discussed in the talk <i><a href="http://www.youtube.com/watch?v=ihzZrS69i_s">A Moving Experience</a></i> at Google I/O 2013<br />
<br />
Code: <a href="http://developer.android.com/shareables/devbytes/LiveButton.zip">http://developer.android.com/shareables/devbytes/LiveButton.zip</a><br />
<br />
YouTube: <a href="https://www.youtube.com/watch?v=uQ7PTe7QMQM">https://www.youtube.com/watch?v=uQ7PTe7QMQM</a><br />
<br />
<div style="text-align: center;">
<iframe allowfullscreen="" frameborder="0" height="315" src="//www.youtube.com/embed/uQ7PTe7QMQM" width="560"></iframe><br /></div>
Chet Haasehttp://www.blogger.com/profile/03250991041464602854noreply@blogger.com1tag:blogger.com,1999:blog-6843566830671277353.post-41435331405955241532013-07-12T09:08:00.000-07:002013-07-12T09:08:07.507-07:00DevBytes: Curved MotionThis is a demo that +Romain Guy and I showed in our A Moving Experience talk at Google I/O this year, showing how to use the existing TypeEvaluator and Animator APIs to get curved motion for your animations.<br />
<br />
In the real world, things don't move in straight lines. Moving items around on the screen should feel as natural as possible; sometimes curved motion can help.<br />
<br />
This episode shows how to use the existing animation APIs to get easy curved motion for your UIs.<br />
<br />
The helper classes come from an article I posted on my blog last year:<br />
<a href="http://graphics-geek.blogspot.com/2012/01/curved-motion-in-android.html">http://graphics-geek.blogspot.com/2012/01/curved-motion-in-android.html</a><br />
<br />
YouTube: <a href="https://www.youtube.com/watch?v=JVGg4zPRHNE">https://www.youtube.com/watch?v=JVGg4zPRHNE</a><br />
<br />
Code: <a href="http://developer.android.com/shareables/devbytes/CurvedMotion.zip">http://developer.android.com/shareables/devbytes/CurvedMotion.zip</a><br />
<br />
<iframe allowfullscreen="" frameborder="0" height="315" src="//www.youtube.com/embed/JVGg4zPRHNE" width="560"></iframe>Chet Haasehttp://www.blogger.com/profile/03250991041464602854noreply@blogger.com0tag:blogger.com,1999:blog-6843566830671277353.post-6817414215371815862013-06-28T10:23:00.001-07:002013-06-28T10:24:08.190-07:00DevBytes: Animating Multiple Properties in ParallelSuppose you want to animate multiple properties in parallel on some target object. How would you do it? ValueAnimator? Multiple ObjectAnimators?<br />
<br />
This episode covers different ways of animating multiple properties, and specifically covers the use of the lesser-known PropertyValuesHolder class.<br />
<br />
YouTube: <a href="https://www.youtube.com/watch?v=WvCZcy3WGP4">https://www.youtube.com/watch?v=WvCZcy3WGP4</a><br />
<br />
Code: <a href="http://developer.android.com/shareables/devbytes/MultiPropertyAnimations.zip">http://developer.android.com/shareables/devbytes/MultiPropertyAnimations.zip</a><br />
<br />
<div style="text-align: center;">
<iframe allowfullscreen="" frameborder="0" height="315" src="//www.youtube.com/embed/WvCZcy3WGP4?list=PLWz5rJ2EKKc_XOgcRukSoKKjewFJZrKV0" width="560"></iframe></div>
Chet Haasehttp://www.blogger.com/profile/03250991041464602854noreply@blogger.com2tag:blogger.com,1999:blog-6843566830671277353.post-42006667003831315192013-06-21T13:04:00.003-07:002013-06-21T13:04:54.825-07:00DevBytes: Animating ListView Deletion: Now on Gingerbread!In this episode, I tried to anticipate the question I knew would come up on my previous show about animating ListView deletion: "But how would I do this on Gingerbread?"<br />
<br />
Here's how.<br />
<br />
YouTube: https://www.youtube.com/watch?v=PeuVuoa13S8&list=PLWz5rJ2EKKc_XOgcRukSoKKjewFJZrKV0&index=1<br />
<br />
Code: http://developer.android.com/shareables/devbytes/ListViewItemAnimations.zip<br />
<br />
<div style="text-align: center;">
<iframe allowfullscreen="" frameborder="0" height="315" src="http://www.youtube.com/embed/PeuVuoa13S8?list=PLWz5rJ2EKKc_XOgcRukSoKKjewFJZrKV0" width="560"></iframe></div>
Chet Haasehttp://www.blogger.com/profile/03250991041464602854noreply@blogger.com10tag:blogger.com,1999:blog-6843566830671277353.post-35642223241997956142013-06-14T14:06:00.002-07:002013-06-14T14:06:14.885-07:00DevBytes: Animating ListView DeletionIt's Friday: must be time for another DevBytes episode.<br />
<br />
Finally, here is the DevBytes episode around the ListView animation demo in the talk <i>A Moving Experience</i> that I gave with <a href="http://google.com/+RomainGuy">Romain Guy</a> at Google I/O last month.<br />
<br />
The code is nearly the same as that in the I/O talk, except I tweaked it to make it more general-purpose. Specifically, it no longer depends on the setHasTransientState() method (introduced in Jellybean 4.1) to keep the views around while fiddling with layout. Instead, it uses an adapter with stable itemIds, and uses those Ids to track where the content is before and after layout.<br />
<br />
As written, the code is still dependent on Android 4.1, but that's only because of the use of ViewPropertyAnimator.withEndAction() method, which is really just syntactic sugar around adding a listener and running the end-action code in the onAnimationEnd() callback. So you could totally port this code all the way back to Android 3.1 (when ViewPropertyAnimator was introduced) or even 3.0 (if you use ObjectAnimator instead).<br />
<br />
Watch the video. Check out the code. Play with ListView. Animate. Enjoy.<br />
<br />
A Moving Experience: <a href="http://www.youtube.com/watch?v=ihzZrS69i_s">http://www.youtube.com/watch?v=ihzZrS69i_s</a><br />
<br />
DevBytes on YouTube: <a href="http://www.youtube.com/playlist?list=PLWz5rJ2EKKc_XOgcRukSoKKjewFJZrKV0">http://www.youtube.com/playlist?list=PLWz5rJ2EKKc_XOgcRukSoKKjewFJZrKV0</a><br />
<br />
Code: <a href="http://developer.android.com/shareables/devbytes/ListViewRemovalAnimation.zip">http://developer.android.com/shareables/devbytes/ListViewRemovalAnimation.zip</a><br />
<br />
<div style="text-align: center;">
<iframe allowfullscreen="" frameborder="0" height="315" src="http://www.youtube.com/embed/YCHNAi9kJI4?list=PLWz5rJ2EKKc_XOgcRukSoKKjewFJZrKV0" width="560"></iframe></div>
Chet Haasehttp://www.blogger.com/profile/03250991041464602854noreply@blogger.com12tag:blogger.com,1999:blog-6843566830671277353.post-3030072918849257522013-06-07T09:28:00.003-07:002013-06-07T09:29:33.277-07:00DevBytes: Custom Activity AnimationsIt's Friday: time for another DevBytes.<br />
<br />
It's been a while, but they're back. At least until the queue runs out again and I write another glut of demos to talk about.<br />
<br />
This episode, and most of the upcoming ones (teaser alert!) are around demos/code that we showed in A Moving Experience, the animation talk that +Romain Guy and I gave at Google I/O 2013.<br />
<br />
<b>Custom Activity Animations</b>:<br />
Window animations provide an easy way to animate transitions between activities. The animations can be customized to some extent, but there's only so much interaction between the launching and launched activities that you can take advantage of with the standard window animations.<br />
This episode covers a different technique for fully customizable animations.<br />
<br />
Video: <a href="http://www.youtube.com/watch?v=CPxkoe2MraA">http://www.youtube.com/watch?v=CPxkoe2MraA</a><br />
<br />
Code: <a href="http://developer.android.com/shareables/devbytes/ActivityAnimations.zip">http://developer.android.com/shareables/devbytes/ActivityAnimations.zip</a><br />
<br />
<iframe allowfullscreen="" frameborder="0" height="315" src="http://www.youtube.com/embed/CPxkoe2MraA" width="560"></iframe>Chet Haasehttp://www.blogger.com/profile/03250991041464602854noreply@blogger.com1tag:blogger.com,1999:blog-6843566830671277353.post-1500054953991809082013-05-17T11:47:00.001-07:002013-05-17T14:15:19.114-07:00Google I/O Presentations Now LiveRomain Guy and I gave two talks at Google I/O yesterday which are now live on YouTube:<br />
<br />
Android Graphics Performance: <a href="http://www.youtube.com/watch?v=vQZFaec9NpA">http://www.youtube.com/watch?v=vQZFaec9NpA</a><br />
<br />
<iframe allowfullscreen="" frameborder="0" height="315" src="http://www.youtube.com/embed/vQZFaec9NpA" width="560"></iframe><br />
<br />
Slides for Android Graphics Performance are posted on <a href="http://www.curious-creature.org/2013/05/17/android-sessions-at-google-io-2013/">Romain's blog</a>.<br />
<br />
<br />
A Moving Experience: <a href="http://www.youtube.com/watch?v=ihzZrS69i_s">http://www.youtube.com/watch?v=ihzZrS69i_s</a><br />
<br />
<iframe allowfullscreen="" frameborder="0" height="315" src="http://www.youtube.com/embed/ihzZrS69i_s" width="560"></iframe><br />
<br />
<i>A Moving Experience</i> Slides:<br />
<ul>
<li><a href="https://sites.google.com/site/androidcontentfromchet/downloads/AMovingExperience.key">Keynote</a></li>
<li><a href="https://sites.google.com/site/androidcontentfromchet/downloads/AMovingExperience.pdf">PDF</a></li>
<li><a href="https://sites.google.com/site/androidcontentfromchet/downloads/AMovingExperience-Notes.pdf">PDF with speaker notes</a></li>
</ul>
<br />
The code from the animation demos will be posted soon, probably in conjunction with future DevBytes episodes.Chet Haasehttp://www.blogger.com/profile/03250991041464602854noreply@blogger.com7tag:blogger.com,1999:blog-6843566830671277353.post-65388524460896707892013-03-28T13:07:00.000-07:002013-03-28T13:07:53.952-07:00For API Nerds: Interfaces and Inner ClassesThis article is for API developers only. If you're writing an application, you may not care about APIs, because you probably don't have any. But if you're writing a library that others will use, public API comes into play.<br />
<br />
API is like a pile of laundry: you can either spread the huge, reeking mess out all over your floor, or you can stuff it into a nice, clean hamper. While the first approach provides the convenience of being able to select each day's pre-soiled attire quickly, since it is arrayed out in front of you when you get out of bed, the second solution presents a clean interface to people that make the mistake of walking into your pathetic, slovenly life.<br />
<br />
Good APIs prefer hampers.<br />
<br />
I was implementing a new piece of API and functionality and wondered the following: Is there any reason to not put my implementation (which I did not want in the public API, and which would be the only implementation of said interface) inside the interface itself? It seems odd, perhaps, maybe even a bit tawdry, but is there anything wrong with it?<br />
<br />
My motivation was simple: I'm adding this API and implementation into a package that already has many classes to wade through. Should I bother adding more noise to the list for an implementation detail of this single interface? Why not put it into the interface file, and just bundle up that implementation in a logical place, tightly bound to the interface that it implements?<br />
<br />
So I did this, coming up with something like the following:<br />
<br />
<pre>public interface A {
void a();
static class AImpl implements A {
@Override
public void a() {
// ...
}
}
}
</pre>
<br />
Additionally, an existing class exposed a single method giving a reference to this interface:<br />
<br />
<pre>public A getA() {
return new AImpl();
}
</pre>
<br />
This worked well - the users of the public <code>getA()</code> method got what they needed: an object of type <code>A</code> with its spectacular, if slightly under-documented, method <code>a()</code>. And I successfully hid the implementation class inside of this same file, as a package-private static class, saving my package the unbearable burden of yet another file.<br />
<br />
Done!<br />
<br />
Then I ran JavaDocs on my project and realized my mistake: my supposedly package-private implementation class was now part of the public API, showing up as the public class <code>A.AImpl</code>. <i>What th-</i>... I didn't say it was <i>public</i>! In fact, I explicitly made it package-private, so that the class exposing the new <code>getA()</code> method could instantiate an instance of that class. So what happened?<br />
<br />
Interfaces happened. Interfaces do not use the same access rules as classes. Instead, all members of an interface are public by default. So while I used the correct (to my mind) syntax for package-private access, I was actually using the correct (to the mind of my interface) syntax for declaring that inner class public, and the JavaDocs did the rest.<br />
<br />
Do I hear you yelling, "You could make it private!?" Or is that just the echo of my internal shouting when I first saw the problem? This is what I tried to do. This fails for (at least) two reasons. One is that I actually needed this class to be package-private (not private), so that I could instantiate it and override it from outside of this interface. An even better reason is that you cannot declare different access permissions than the default that the interface uses. In this case, that means that I cannot have a public interface with a private inner class. I could declare the entire interface to be private... but that defeats the whole thing I was going for by exposing the interface <code>A</code> as a public API.<br />
<br />
There are other ways around this. For example, there is a mechanism we use in Android framework code, <code>@hide</code>, to solve the problem of having to expose API internally but not wanting it to be a part of the public API (a workaround for the language not having the ability to differentiate between internal and external access to library APIs). But at the point where I considered using this workaround, the awkwardness of putting the class inside of the interface just got to be too much.<br />
<br />
In the end, I just pulled the class out and put it at the same level as <code>A</code>. It added another file to the package, but that really wasn't that big a deal anyway. And it was certainly better than the mess I was creating with my class-inside-interface approach.<br />
<br />
The moral of the story is: API design is tricky. Consider not only the internal implementation details ("Can I make my life easier by implementing the solution in this particular way?"), but also (and <i>wayyyyy</i> more importantly), "Can I make the API, and therefore the lives of external developers, better by doing it in this other way?"<br />
<br />
Here is a technical diagram, illustrating the problem and the original solution:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5V5-5FySrzMDj0GJafRBLORhuLYzWitmDFjRrfgN2ZweIQG8gRqjy1EFE_ATwzCnp8gma62qsShm2couDSItYNlKoFFLOrgoO_vPeGxgPb-5PC1CIl6XsBQyRg2FUBFtfcRogzG9k10U/s1600/MessPlusRug-1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="206" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5V5-5FySrzMDj0GJafRBLORhuLYzWitmDFjRrfgN2ZweIQG8gRqjy1EFE_ATwzCnp8gma62qsShm2couDSItYNlKoFFLOrgoO_vPeGxgPb-5PC1CIl6XsBQyRg2FUBFtfcRogzG9k10U/s320/MessPlusRug-1.png" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjck7ZRV1A1pZkZvh85VzT-r0QPcqJ2kGarUtl-myxQzfcZWNpuz725dODufPHRBKWt3oJY167eXY90xUui6fi1yaStnD2ycR-LAnH4Tg1EMFWdaeWGaS_d6hR7ZCYGaIlODutvI-p1OD0/s1600/MessPlusRug-2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="206" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjck7ZRV1A1pZkZvh85VzT-r0QPcqJ2kGarUtl-myxQzfcZWNpuz725dODufPHRBKWt3oJY167eXY90xUui6fi1yaStnD2ycR-LAnH4Tg1EMFWdaeWGaS_d6hR7ZCYGaIlODutvI-p1OD0/s320/MessPlusRug-2.png" width="320" /></a></div>
<br />Chet Haasehttp://www.blogger.com/profile/03250991041464602854noreply@blogger.com5tag:blogger.com,1999:blog-6843566830671277353.post-2388301065073251362013-03-22T10:28:00.002-07:002013-03-22T10:28:48.699-07:00DevBytes: Layout TransitionsThe LayoutTransition class (added in Android 3.0) enables easy fade/move/resize animations when items are added to or removed from a ViewGroup, usually with just one line of code. This video shows how this works and also shows the new ability added in JellyBean (Android 4.1) to animate other changes to the layout as well, not limited to items being added or removed.<br />
<br />
YouTube:<br />
<a href="https://www.youtube.com/watch?v=55wLsaWpQ4g">https://www.youtube.com/watch?v=55wLsaWpQ4g</a><br />
<br />
Code:<br />
<a href="http://developer.android.com/shareables/devbytes/LayoutTransChanging.zip">http://developer.android.com/shareables/devbytes/LayoutTransChanging.zip</a><br />
<br />
<div style="text-align: center;">
<iframe allowfullscreen="" frameborder="0" height="315" src="http://www.youtube.com/embed/55wLsaWpQ4g" width="560"></iframe></div>
Chet Haasehttp://www.blogger.com/profile/03250991041464602854noreply@blogger.com7tag:blogger.com,1999:blog-6843566830671277353.post-24547575066916145542013-03-15T08:29:00.003-07:002013-03-15T08:29:35.564-07:00DevBytes: PictureViewer<span style="background-color: white; font-family: arial, sans-serif; font-size: 13px; line-height: 18px;">PictureViewer: How to use ViewPropertyAnimator to get a cross-fade effect as new bitmaps get installed in an ImageView.</span><br />
<span style="background-color: white; font-family: arial, sans-serif; font-size: 13px; line-height: 18px;"><br />
</span> <span style="background-color: white; font-family: arial, sans-serif; font-size: 13px; line-height: 18px;">TransitionDrawable is a handy and easy facility for cross-fading between two drawables. But if you want to cross-fade between an arbitrary set of images, you might want something more general-purpose. Here's one approach.</span><br />
<br />
YouTube: <a href="https://www.youtube.com/watch?v=9XbKMUtVnJA">https://www.youtube.com/watch?v=9XbKMUtVnJA</a><br />
<br />
Code: <a href="http://developer.android.com/shareables/devbytes/PictureViewer.zip">http://developer.android.com/shareables/devbytes/PictureViewer.zip</a><br />
<br />
<iframe allowfullscreen="" frameborder="0" height="315" src="http://www.youtube.com/embed/9XbKMUtVnJA" width="560"></iframe>Chet Haasehttp://www.blogger.com/profile/03250991041464602854noreply@blogger.com2