Monday, December 31, 2012

Titanium First Look and Calculator

Appcelerator's Titanium Studio (Titanium) is an interesting mobile development environment. Writing code in it isn't like anything else I've coded in it. This isn't necessarily bad, but it does take some getting used to. This post will be a multi-part review and tutorial. My goal is to learn the system by writing a calculator app. I am working with version 3.0 of Titanium. If you have read any of my previous posts, you may know that I have written a calculator app in jQuery Mobile for mobile websites and then easily ported it to PhoneGap for both iOS and Android. The question is how hard is it to build the calculator in Titanium.

This isn't a getting started tutorial. Titanium already has excellent tutorials to do that on their site. Instead, it is an exploration. If you need a tutorial check out the ones on Titanium's site at: Quick Start.


What is Titanium?
A lot of people have the incorrect assumption that Titanium is the same thing as PhoneGap, it is not. Yes, they both make it possible to write cross platform  mobile code in JavaScript for iOS and Android, but that is about all that they have in common. I like PhoneGap, it is essentially mobile web development moved onto mobile devices. Everything familiar to web developers is there, including the dreaded DOM. 

Instead Titanium wraps native UI in JavaScript calls. This enables skilled Titanium programmers to creates apps which are indistinguishable from native ones. This is very different from PhoneGap. At best PhoneGap enables the you to create programs which fake the appearance of native apps, but lack their speed.

In order to build iOS code, you will need an Intel Mac, the same basic requirement that traditional iOS programming requires. Both PhoneGap and Icenium now make it possible to bypass the Mac requirement, but Titanium does not. But this isn't all bad. Just like traditional iOS, you can pick your deployment target. It can be a provisioned iPhone or iPad or their simulator.

User Interface
Titanium is something different. First off, there is no DOM. That's right the worst API ever designed, the Document Model Object, doesn't exist in Titanium. While that should be good news, it does create a problem. How do you create UI? Unfortunately it is via code, which quite frankly sucks. I've been coding a long time, I remember the early days of UI programming, how fun it was to code out each and every UI element. Then I remember what is was like when NextStep arrived. It had the Interface Builder, it wrote the UI code for you, brillant. And while HTML/CSS isn't the ideal UI creation combo, it is leaps and bounds above building UI in code. Plus, it has the additional advantage of being well documented.

Now, in all fairness, I can see references in the documentation and website to something called, Alloy. And it appears that Alloy builds UI with XML, like Android or Windows Phone. I will check it out in a later post. But if Appcelerator really wants to make Titanium world class, it has to make a UI builder for it. 

Debugging
One of the worst parts of PhoneGap is debugging. No matter how good your code is, eventually you will need to debug it and nothing beats being able to set good old fashion breakpoints. PhoneGap doesn't really have a debugger. Wait - before people flood the comments - I know that there are ways to do debugging in PhoneGap. But none of them are optimal, none. Being able to stop the code at any arbitrary point and examine the environment - is a great help and a necessary part of development.

With Titanium you have it. I can set a breakpoint and run the code on either an Android or iOS device, emulator, or simulator. Being able to set a breakpoint is a real boon and helped me several issues already, especially since I refused to RTFM.

The Calculator
I began building the application by selecting the Single Window Application template. This template creates several versions of ApplicationWindow.js. Titanium doesn't try to create one code base for all systems. Instead it gives the developer a way to share a great deal of code between environments, but not all of the code. Each version of ApplicationWindow is tailored for a different platform. It also creates a view, FirstView. Think of windows as HTML pages and views as divs. 

I renamed FirstView to KeyPad. All of the View code, this time view as MVC, goes in it. Titanium's support of CommonJS Modules makes it very easy to implement separation of concerns. The is no global space like traditional DOM programming. All of the communication between modules has to be planned.

My plan for the calculator is that KeyPad will be the view. App the controller. And a still unwritten module named Logic will be the model. Communication between the different modules will be mainly via events. And here is where I finally needed to RTFM. 

In DOM programming to do communication between modules I would normally fire a custom event off of the Document, but there is no document in Titanium. I didn't want to do it off of the KeyPad, since the model should have no knowledge of the KeyPad. Finally, I found that you can fire events off via Ti.UI.fireEvents/addEventListener. I coded this up and tried it out. It worked under iOS, but not Android. I read the documents over and over but there wasn't any information about why this doesn't work under Android. Finally I googled it. Seems I'm not the only one who has encountered this issue. The solution is to use Ti.App.fireEvent/addEventListener instead. No explanation given as to why. This is part of the reason why I don't like to google things, I want to why not just how.

So far I have the code working in the KeyPad firing events. And some temporary code in app.js receiving them. Most of the time spent so far has been in hand coding the UI. It sucks but at least things work better than in DOM programming. I decided to use percentages for the buttons. In DOM programming width percents work correctly but height only works if you hard code the height of the parent container. In Titanium height percents work is exactly as you would think they should intuitively. This makes it a lot easier to code UI to be flexible based on its environment.

Summary
So far I like Titanium. It was a lot easier to get the environment up and running than PhoneGap. Plus I like being able to build for Android or iPhone in the same environment. I haven't finished the calculator yet, but I will. The complete source code is on GitHub at: Titanium Calculator. Please check it out. I will finish it sometime in January 2013 and let everyone in a future post. 

Here is the link to second part of this post: Titanium Second Look.

Here is the KeyPad as it exist now:

Sunday, December 30, 2012

5 Quick JavaScript Improvement Tips

Here are the slides from a presentation I gave earlier this year, some quick and easy ways to speed up your JavaScript code. 

Saturday, December 29, 2012

Octane JavaScript Benchmark Scores

Apple iPhone 5
Nokia 920
Google Nexus 4
In my last post, I showed HTML5 and CSS3 test scores for three super phones. Modern web apps consist of three parts: content, presentation, and behavior. HTML5 is the content. CSS3 is the presentation and JavaScript, the final leg of this tripod, is the behavior. The iPhone 5 and Nexus 4 are essentially tied in their implementations of HTML5 and CSS3, with the Nokia 920 hot on their tails. But what happens when we throw JavaScript performance into the mix?

Benchmarks can be problematic. They normally chose to narrow of a focus, which allows them to be exploited. More than one manufacturer has modified their code to exploit weaknesses in a benchmark and make themselves appear faster. Octane is Google's new JavaScript benchmark. Unlike others, it runs a suite of tests which mimic the behavior of real world modern websites. If you would like to know more about Octane, here is the link: Chromium Blog About Octane. If you would like to run the benchmark yourself, go here: Octane.

Here are the Octane scores for the super phones. Please take these score with a grain of salt. 


  • Apple iPhone 5 -  1403
  • Google Nexus 4 -  1267
  • Nokia 920      -   601 
  • Chrome 23 (OSX)- 12410


It isn't surprising to see the iPhone 5 leading the pack here. Apple spends a lot of time and resources keeping their JavaScript engine top-notch. The Nexus 4 is 10% slower, which is a bit surprising since desktop Chrome is so fast. But the total surprise is how far behind the Nokia is. Now it is entirely possible that I didn't execute the benchmark correctly. The other two phones, I own and know how to work. The 920 was borrowed and their may have been apps running in the background, stealing cycles from the benchmark. But then again, JavaScript performance has always been a weak spot for Microsoft.

I wouldn't base my decision to buy or not buy any phone solely on benchmarks. I would consider how the phone fits into my lifestyle a better measure. But benchmarks are cool. If you decide to benchmark your own device, please let me know the results in the comments section.




Thursday, December 27, 2012

HTML5, CSS3 Test Redux

HTML5 and CSS3 are full of lots of sweet features. But it can be tricky to determine which features your device supports. Luckily there are sites out there which will report on the features  your device support.

To test HTML5 features, there is the  appropriately named, HTML5Test.com and for CSS3, there is the equally appropriately named, CSS3Test.com. Back in August, I ran three phones through the two tests and reported on their scores. Back then the phones were: the Apple iPhone 4, the Google Nexus One, and the Samsung Focus Flash. They represented iOS, Android, and Windows Phone 7 respectively.  If you are curious here's link to that post:


Well, I have a new crop of phones on hand, this time all flagship phones for their respective O/S. I have Apple's iPhone 5, Google's Nexus 4, and representing Windows Phone 8 (WP8), the Nokia 920. 

  • Apple iPhone 5 - HTML5 386 and  9 bonus points - CSS3 55%
  • Google Nexus 4 - HTML5 385 and 11 bonus points - CSS3 54%
  • Nokia 920      - HTML5 320 and  6 bonus points - CSS3 54% 
  • Chrome 23 (OSX)- HTML5 448 and 13 bonus points - CSS3 63%


The biggest surprise in the crop is the Nokia 920. Windows Phone 7 had very marginal support for HTML5 or CSS3. Its score was drastically lower than the iPhone 4 and even the Nexus One which came out much earlier. Well, the 920 isn't anyone's whipping boy. It ties the Nexus 4 in its CSS3 score and falls only one percentage point below the iPhone 5. In HTML5, Windows Phone 8 still lags behind the iPhone but it is only by 66 points, not 166 points of the last test. 

Vs. Desktop
Google's offering still lags behind Apple's iPhone 5, but now it is only by one point in the HTML5 test and one percentage point in the CSS3 test. For comparison, Chrome 23 running on Mac OSX Mountain Lion gets scores of 448 on the HTML5 test and 63% on the CSS, so there is still a lot of room for improvement for mobile browsers. Plus, this should serve as a caution to those of us doing mobile development and testing our apps on the desktop. Desktop browsers are still more capable than those on mobile devices, so testing on the device is still mandatory.

What about JavaScript?
JavaScript is the language of the web and there are also websites to test your device's JavaScript implementation speed and capabilities. In an upcoming post, I will reveal how well these devices do with JavaScript.

Tuesday, December 25, 2012

Introduction to Node.js Talk

My good friend Chander Dhall, has asked me to fill in for him on Monday, January 14th, in front of the Meetup group, HTML5/Node.js Los Angeles. The title of the presentation is, Introduction to Node.js. I am really excited to do this talk, as you might guess by some of my posts, I am a huge JavaScript fan. It is my favorite language and the language of the web. Using Node allows me to code in my favorite language on both sides of my web apps. 

It can be difficult, to figure out how to Node via most of the standard Hello World websites floating around on the net. In this talk, I will show how to construct a basic, but useful website and add a backend REST service to it. I will also demonstrate my workflow. How I build and test on my local box, before and pushing out to my public server. I will also provide a list of my tools, which editor, unit test framework, and Git clients I use everyday.

So if you are in the area, please come to this talk. Information and directions are on the Meetup page at: http://www.meetup.com/nodela/events/91265402/. After the talks is done, I will make my source code and slides available. Hope to see you there.

Thanks again to all who attended. It was great meeting all of you. Here is the link to the source code on GitHub.


If you attended the talk, please rate it:

Saturday, December 22, 2012

Turning Off Google+ Community Notifications


Nothing here about Community Notifications
I like the new Community feature of Google+. It is great having another cool way to keep up with developers worldwide, but I hate all the notifications. I neither need nor want an email every time a member leaves a post.  Unlike other parts of the Google+ world, there is no setting for turning on or off Community notifications in the Accounts -> Google+ section. But don't despair, the switch is hiding in plain sight. 

On Community page itself, below the community's logo and membership total, next to the Action drop down, there is a button with a bell icon. Clicking the button turns notification on and off. 

Thursday, November 15, 2012

Quick & Dirty Mobile Web with jQuery Mobile


Here are of the slides from my JS(Saturday) talk: Quick & Dirty Mobile Web with jQuery Mobile and ASP.NET MVC. Thanks again to all of those who listened to my talk. It was one of the best receptions I've ever had. 

 The source code to match the slides is at:

PHONEGAP TRAINING
The first in series of one day, intense Saturday training classes will be on PhoneGap in May 2013 in Los Angeles. The exact date, location, and course outline will be  announced in February via EventBrite, Twitter, Google+ and of course this blog.



Saturday, November 10, 2012

JS(Saturday) Wrap Up


Thank you to all of those who attended JS(Saturday) and especially those who attended my session: Quick & Dirty Mobile Web with jQuery Mobile and ASP.NET MVC. Below you will find the links to the source code and the slides.






Please take a minute to rate my talk. These ratings help me get noticed and asked to speak at other venues. So if you liked my talk and hope I do more, please rate me by clicking the widget below.


Friday, November 9, 2012

Not Enough jQuery

A colleague sent me this link and I found it hilarious. You can never have enough jQuery. Check it out: 



 http://www.doxdesk.com/img/updates/20091116-so-large.gif

Let me know what you think.

Wednesday, October 24, 2012

jsSaturday


On Saturday, November 10, 2012, I will be speaking at JavaScript Saturday.  This event will be held in Long Beach, California. Here is the description directly from JS(SATURDAY) site:

Javascript Saturday is a complete one-day Training from the best of the Javascript experts aimed at all levels of expertise.

Have no experience in Javascript? - Go from beginner to advanced in a day.

Want to know about Javascript frameworks and how to advance in your career - This event is for you.

Victim of Information overload? - You will learn what you need to know to succeed and become an expert in JavaScript.

I love attending events like this. While I can learn from books and online tutorials, nothing beats being able to ask an expert a question. My session will be on jQuery Mobile. This will be an entirely new talk geared towards teaching you the things you need to know to get up and running as quickly as possible. 

This event has a regular price of $95, but I have the promotional code for you. It will lower the price down to just $30. If you can't get your company to pay $30 for all day training, then you really should think about finding a new job. The code is: "RiaConsultingLLC". Enter it into the text box for the promotional code. 




If you come, be sure to say, "Hi." I will be there pretty much the whole day, so you will have plenty of time to ask me jQuery Mobile or JavaScript questions.

Client Side Mobile Device Detection

Device detection can be very complicated. There are entire businesses based on correctly identifying the user's device. Luckily for us to poor to afford such services there is another way to do device detection which doesn't require us to re-invent the wheel.

The actual detection logic comes from Chad Smith and his site: http://detectmobilebrowsers.com. It uses a regular expression to test the user agent string from the device. So far it has correctly detected every mobile device I have thrown at it, but there is a possibility that it may miss a device. Luckily the site is updated frequently, in fact it was just updated six days ago, at the time of writing. I have created an example program which shows one possible way to integrate it into your code. Chad includes code for just about every known web environment, from Apache to Rails, including my favorite, JavaScript.


The site is very simple. It consists of three pages: index.html, desktop.html, and phone.html. Index.html loads and executes the detection script. If it fails, i.e. is not a mobile device, it then jumps to desktop page. If JavaScript is turned off, it simply throws up links to both the desktop and phone pages and allows the user to choose which one they want. 

One important thing to note is that only the index page does detection. If the user wants, we allow them to navigate to the desktop page on their phone. This is important, since most desktop sites have more features than their mobile counterparts. If the user isn't able to achieve their goal on the mobile site and you don't allow them to go to the desktop site, they might not come back.


The key part of the detection script, detectmobilebrowser.js, is towards the end. There it needs a link to go if it successfully detects a mobile browser. In my case it is phone.htmlThe demo code only detects mobile phones, not tablets. There are instructions on how to change the detection code to also detect tablets here.


To try the detection code for yourself, click the link below then select
"Mobile Detect".


For your own site, I recommend that you download the detection code from Detect Mobile Browsers. No telling when the code may get updated again. Also, if you use the detection code in your business, please consider giving Chad a donation to encourage him to keep it updated.


Thursday, October 18, 2012

Windows 8 Store App with JavaScript - First Look

I have a great fondness for JavaScript. When Microsoft announced that it was possible to build Windows 8 Store (formerly Metro) apps with JavaScript, HTML, and CSS3, I had to check it out for myself. 

Microsoft has made a large number of resources available for developers wishing to learn Windows 8. There are websites, videos, books, and hands on labs. All of this material is being offered for free. 

I chose the book, Programming Windows 8 Apps with HTML, and CSS, and JavaScript by Kraig Brockschmidt. The book is available for free at:


The book is chocked full of information, perhaps a little too much. I was looking for the general information about the differences between normal web programming  and programming a Windows 8, but I got a lot more than that. I am not sure what to make of it. I am not into step by step tutorials. Give me some theory, some example snippets, and then leave me alone. But there are a lot of people who like that style and it is at the right price. The book has  12 chapters. They cover lots of ground including: app anatomy, page navigation, controls, data binding, collections, layout, files, input and sensors, and media. 

To help me get my head around Win 8 coding I decided to port a game I am working on. It was surprisingly easy. In just a few hours I was able to get the game to the same state it was in as a web app, then easily add some cool built in animations to it. It went so well that I've decided to bring the app out for Windows 8 first. 

Overall Microsoft has done an amazing job of making it easy to build Win 8 apps in JavaScript. If you haven't tried it yet, I highly recommend that you do.

Wednesday, October 17, 2012

Free JS Design Patterns Book

I know how tough it can be when you want to learn and don't have a lot of money. So every time I come across a free or low cost resource, I promise to share the wealth. 

Here is another free book to help all of you JavaScript padawans, Learning JavaScript Design Patterns. Once again this book is by Googler Addy Osmani.

This book is great introduction to design patterns in general and JavaScript design pattern in specific. It has fifteen chapters covering topics like:  writing design patterns, categories of design patterns, anti-patterns, jQuery plugins, and modern module design patterns. 

This time around the book isn't downloadable, it is a website with accelerators to the chapter that you are looking for. I have it bookmarked on my ASUS Transformer tablet. For those of you who prefer an actual book or ebook, here is the link to it on O'Reilly's website. 


It will cost you a bit of money, but you help keep it free those who can't afford to buy it.



Tuesday, October 16, 2012

Free Backbone.js Book


As many of you know, I am a fan of Backbone.js. In fact, it has been the subject of talks that I have given recently. After the talks, people often ask for more references on backbone, but other than a few websites, there wasn't much available. But now there is and it is free!



Backbone Fundamentals is a book by Googler and backbone expert, Addy Osmani. The book is available in epub format for free on GitHub. Here is the link: Backbone Fundamentals.

The contains 165 pages divided into 10 chapters. It covers a lot of topics, things like the fundamentals, the internal workings of Backbone, building an application, common problems and solutions. It even includes one of my favorite subjects, building mobile applications with Backbone and jQuery Mobile. It has an easy to read, casually informative style which is packed fully of  coding knowledge. And it can't be beat for the price, so be sure to download it.

Be sure to check out my in-depth and affordable JavaScript Workshop coming this May to Southern California. I am partnering-up with the South Bay Mobile User Group and PeopleSpace for this course. I challenge you to find deeper JavaScript training for less. Hurry before it fills up.




Monday, October 15, 2012

jQuery Mobile UI Builder

If you've used either Apple's Interface Builder or Microsoft's Blend to build UI, then having to do it by hand in HTML seems like a big step backwards. But there is help and it is free. The Intel Open Source Technology Center has released its Rapid Interface Builder (RIB) tool. It runs only in Google Chrome, but it will save you huge amounts of time laying out your UI.

RIB supports both jQuery Mobile and Tizen (a new mobile still in development) widgets. It allows create your UI in the browser then download the source code to your PC. Later I will do a more in-depth walk-through of this amazing tool. 

Rapid Interface Builder


Layout mode
Preview Mode

SoCal Code Camp LA 2012 Wrap Up

A big thanks to all of the people who attended my four sessions Saturday and Sunday. It is always humbling to see a standing room only crowd listening to me speak. If you haven't done so already: please rate my talks. Here is the link to my speakerrate profile. 

All of the slides to all of my sessions are on slideshare.net. And all of the source code is on GitHub.

For those that attended the packed Beginning HTML5 Mobile Game Programming session, on Tuesday October 16th at 6PM PDT, I will be doing a live Google+ Hangout of an enhanced version of that session. This will be the first of six sessions as we build a complete game from start to finish. The first nine people will be able to ask me questions, the rest can watch it streamed live over YouTube. Hope to see you there.

Be sure to follow me on Twitter for the latest mobile and mobile web development tips and tricks, @therockncoder.

Between sessions on Saturday

Thursday, October 4, 2012

My iPhone 5 Nightmare

I want to say right from the beginning that I don't have an agenda. I was very reluctant to write this post. My blog is normally about development, not about ranting, but I have an issue that no one else seemed to be having with the new iPhone 5. I am not a fan boy or hater of any smart phone platform. I own an Apple iPhone 4, a Google Nexus One (Android), and a Samsung Focus Flash (Windows Phone 7). I like and dislike things with all of them. When AT&T, my carrier, announced that it would allow those of us who have the grandfathered unlimited data plan to keep it with higher data speed iPhone 5, I decided to buy one and I now regret that decision. 

My first iPhone 5 arrived on the afternoon of September 21st. Once I got home, I got the phone up and running in a short amount of time. Backing your data to the iCloud works well. The phone worked great over the weekend.

Monday morning is when things took a turn for the worse. I was listening to music over wireless bluetooth while running. It was still early in the morning, the sun hadn't came up yet. Roughly nine minutes into my run the music stop and my phone appeared to have turned off. A few things of note:

  1. The phone was attached to its charger all night - it had a full charge
  2. The headphones (Motorola S305) were charged and had worked flawlessly for years
  3. The phone was not damaged in any way, shape, or form
I tried to turned the phone on, but it would not turn on. Roughly thirty minutes to an hour later the phone came on by itself. Everything seemed OK except it no longer had a cellular signal. Instead of "AT&T" in the status bar, there was the message, "Searching...". I let the phone sit like that for about an hour before I turned it off and popped the SIM card out. My team at work was close to a major production deployment of our website and I didn't need any distractions. 

After our deployment, I began to make an appointment for the Genius Bar at a Apple store near my work. On that site it gave me some suggestions of how to resolve the issue myself. When I tried to re-install iOS 6 onto the phone, the installation failed with an error code of "-1". Now my phone was completely useless. I made the appointment to speak with a Genius. 

When I arrived that Apple store a few minutes ahead of my appointment it was crowded. After checking in, I waited. My appointment was for 3:50 and by 3:53 a Genius was calling my name. The Genius was unable to fix my phone however. When he tried to install iOS 6, it failed for him too. I braced myself to be told something unpleasant, but the Genius walked over to a drawer, opened it, grabbed a brand new phone. He typed some information into his computer then asked for the SIM card.  I popped the SIM card out of my Windows Phone 7 and he popped it into the new iPhone 5.  After following the activation steps, I was in business again. Unfortunately this story doesn't have a happy ending yet. 

This morning, October 4th, I went for a run again. Once again listening to music over bluetooth on my iPhone 5. When I passed the nine minute mark still listening to music, I smiled, but it wouldn't last. At the 17 minute mark, the phone crashed exactly as it had before. Roughly 30 minutes later it rebooted on its own and once again the message, "Searching..." appeared at the top of the status bar.  I can no longer make phone calls.

I know at least half a dozen people who have iPhone 5s, none of them are having any issues and they are all happy with it. I, unfortunately, am very unhappy. I have made another appointment to speak with a Genius at the Apple store. I will probably call AT&T this evening to see about returning the phone and getting my money back.

UPDATE - 5 October 2012

The end result of my trip to the Apple store was iPhone 5, number 3. The Genius, Mike, was super cool and seemed very knowledgeable but was mystified as to why my phone couldn't get out of search mode. He tried several things including reseting the network  connection, but nothing work. He did posit a theory that there may be a bad file in my cloud backup, which I used when activating both previous phones. Activating it as a new phone isn't really that much of a hassle since I have all of my contact information in my Google account and I don't have that many apps installed.

I still don't have music on the phone so I ran with my Windows Phone. Besides I am too gun shy to try it. Sometime after code camp, when I have my music back on the phone and time for a possible trip to the Apple store, I will try running with it again.

Wednesday, September 12, 2012

Fixing an Android Memory Leak

One of the most dreaded bugs in Android is a memory leak. They are nasty because one piece of code causes an issue and in some other piece of code, your application crashes. The general rules of causality are violated. My adventure begins in the Android Developer console's Application Error Reports section, there I found several crash reports labelled, OutOfMemoryError.

Out of memory errors can be divided into two basic type: type one is the obvious - you are actually out of memory. You are trying to allocate more memory than your app's heap has. Type two is a memory leak, this type is harder to find. Looking at the crash reports it was easy to tell that I had a leak. The first clue is that the crashes are not coming from one place but from several. This is part of what makes memory leaks tough.

At this point I decided to do a low level check for the issue. I hooked up a phone to my PC and ran DDMS. Android's garbage collector writes information to LogCat as it is running. This information is short but sweet.

GC_CONCURRENT freed 1837K, 41% free 6232K/10503K, external 6427K/7571K, paused 3ms+4ms
GC_FOR_MALLOC freed 486K, 41% free 6372K/10695K, external 6764K/7459K, paused 47ms
GC_EXTERNAL_ALLOC freed 1147K, 41% free 6414K/10823K, external 7002K/7459K, paused 60ms

The most important piece information above is the highlighted percentage free. This number will fluctuate as you use your application but it should hover around certain values. You can never use 100% of the memory. Below 30% the system will begin to respond sluggishly and the time needed to allocate memory will go from less than 10ms to above 100ms. Below 20% and you will start seeing messages like:

Clamp target GC heap from 32.222MB to 32.000MB
GC_FOR_MALLOC freed 0K, 18% free 19695K/24007K, external 7950K/8765K, paused 171ms

These messages are an indication that the system is getting ready to crash.

As I stepped through the app, everything looked fine. I would watch the memory chunk downward and just when I thought I had found the culprit, it would suddenly shoot back up. Then I realized what I might be doing wrong. We have an active base of over 500,000 users. In the field, users are not doing a tour of all of the apps features as I was doing. If they were we would see a lot more than the average of six reports per week over this issue. Instead, I reasoned this was probably more a case of a user doing something excessively, such as navigating between two pages or repeatedly tapping a button.

I knew that the app is usually trying to allocate memory for bitmaps from the crash report. I knew the area of the app where the most bitmaps are allocated. And I reasoned the type of behavior the user might be doing before the crash. Now all I needed was a bit of luck.

Eureka

One section of our app consist of about eight pages hooked up to a ViewFlipper. On the last page of the flipper, the user is taken back to the first page. It is a loop and it goes in both directions. What would happen if the user kept looping through the pages, I wondered? The answer: memory would slowly decrease. I almost didn't notice it, but each loop through the pages would decrement a percent or so from the free memory. Now I was sure I had a memory leak but I still didn't know the cause.

(initial)
GC_CONCURRENT freed 1803K, 43% free 5747K/9991K, external 6289K/7624K, paused 3ms+4ms
(first pass)
GC_CONCURRENT freed 1486K, 32% free 8375K/12295K, external 12760K/12988K, paused 3ms+5ms
(second pass)
GC_EXTERNAL_ALLOC freed 919K, 30% free 10014K/14279K, external 11183K/11636K, paused 93ms
(fourth pass)
GC_EXTERNAL_ALLOC freed 6K, 29% free 11111K/15559K, external 9558K/10063K, paused 94ms

DDMS and the Eclipse Memory Analyzer Tool

The DDMS has some built-in and rudimentary heap tools, but when paired with the free Eclipse Memory Analyzer Tool or MAT, they shine. MAT can take the heap dumps that DDMS creates and fully analyze them. It does way more things than I have the time to learn, but I did figure out enough to have it help me find my issue. All I needed to do is generate the Leak Suspects report.

Note: Memory profiling in the DDMS is very resource intensive, so much so that I would only recommend doing it on a device and never on the emulator.

To generate the Leak Suspects Report:
  • Once you have the app in the area of the suspected memory leak, click the Update Heap icon
  • Do some activity to cause some memory to leak
  • Click the heap dump icon
  • On the Getting Started Wizard, click Leak Suspects Report, then click Finish.
  • After a delay, the Leak Suspects report will appear




The Leak Suspects Report

The report will generate a graph indicating things it thinks may be memory leaks. Be careful here. Not everything it thinks may be a leak actually is. Remember your program needs to have some objects allocated in order to function. What you really need to be suspicious of is things that have multiple instances allocated or things which are using huge amounts of memory. In my case, it was problem suspect #2. It showed 10 instances of the Dealer object allocated. As I looped through the pages the number of these objects grew and so did their size. But why? The Dealer object was a very simple class. It held the name, address, telephone number, etc. of a dealer. Yet according to MAT it had a shallow heap size of 64 bytes, but a retained heap size of 1.2 MB - what?

Leak Suspects

Leak Suspects

It is All in the Details

In order to determine why a simple object, which should be no more that a few hundred bytes was hanging onto 1.2 MB, I clicked on the Details link. This causes three more reports to appear: Shortest Paths To the Accumulation Point, Accumulated Objects, Accumulated Objects by Class.

Each of these reports told me lots of information. The Shortest Paths To the Accumulation Point report show me that my simple Dealer object was holding onto a lot of stuff including an activity. This is very common cause of memory leaks in Android. An object is somehow holding onto a reference to an activity causing it to not be garbage collected. The Accumulated Objects report showed me that there were Linear Layouts involved in this too. And finally the Accumulated Objects by Class report told me the final key pieces of information I needed. There were TextViews and DealerInfoView objects involved too.

Shortest Paths To the Accumulation Point


Accumulated Objects

Accumulated Objects by Class

The DealerInfoView object is only new'ed up in one place, in the adapter for the Dealer ListView. Once I looked at the getView() method I saw the problem.

@Override
public View getView(int position, View convertView, ViewGroup parent) {
 View dealersRow = inflater.inflate(R.layout.carhubdealersrow, null);
 Dealer dealer = dealers.get(position);
 new DealerInfoView(dealer, dealersRow);
 Button getQuote = (Button) dealersRow.findViewById(R.id.ButtonGetQuote);
 getQuote.setOnClickListener(new DealerQuoteDialog(activity, dealer, getFromHub()));
 ImageButton buttonDirections = (ImageButton) dealersRow.findViewById(R.id.ImageButtonDirections);
 buttonDirections.setTag(dealer);
 buttonDirections.setOnClickListener(new Directions(activity));
 return dealersRow;
}

The dealers object is an ArrayList of Dealer objects. It exist outside of this adapter. The adapter is managed by Android. So when the garbage collector tries to release this view it can't because it doesn't control the dealer object. The solution to this issue was relatively simple, create a local copy of the dealer object. The changed method is below. Only one small change was necessary to fix a painful bug.

@Override
public View getView(int position, View convertView, ViewGroup parent) {
 View dealersRow = inflater.inflate(R.layout.carhubdealersrow, null);
 Dealer dealer = new Dealer(dealers.get(position));
 new DealerInfoView(dealer, dealersRow);
 Button getQuote = (Button) dealersRow.findViewById(R.id.ButtonGetQuote);
 getQuote.setOnClickListener(new DealerQuoteDialog(activity, dealer, getFromHub()));
 ImageButton buttonDirections = (ImageButton) dealersRow.findViewById(R.id.ImageButtonDirections);
 buttonDirections.setTag(dealer);
 buttonDirections.setOnClickListener(new Directions(activity));
 return dealersRow;
}

Because the Dealer object is no longer a pointer to a foreign object, the garbage collector is now free to collect it. The memory leak is now plugged.

Tuesday, September 11, 2012

PhoneGap Android, jQuery Mobile, HTML5 Canvas, and Touch-based Drawing


This is the PhoneGap version of the jQuery Mobile touch-based drawing programing. For the most part all of the HTML and JavaScript remains the same between the two versions. There are only a few difference which should be explained. If you haven't read the previous post, you should before continuing.


jQuery Mobile, HTML5 Canvas, & Touch-based Drawing.

Orientation

The easiest way to handle orientation in an Android application is not to,simply supporting portrait would be enough. So I made the following change to the <activity> tag in the manifest:


  <activity
    android:name=".MainActivity"
    android:screenOrientation="portrait"
    android:label="@string/title_activity_main" >

Since we don't seem to receive orientationchange events from within the app's code I removed the event handler for it and the resize event. 

Other than those two changes the rest of the code was lifted as is from the web version of the application. The complete source code is in my GitHub repo. It is for Android and the Eclipse IDE. Hopefully a little later in the week I will do a Intellij IDEA version and also the iOS version.