Let’s say you want to build an RSS reader in AIR, and you need full HTML support to display the feed. Your RSS reader might switch between a few feeds so you are also loading the XML dynamically.
You’ll notice two things:
- As the app runs, your memory usage keeps growing and growing.
- Some RSS entries are too big to be displayed entirely.
This is because:
- XML is not being garbage collected.
- The HTML component’s height can only be 2880. (or 4096 in AIR2)
A solution for the HTML height limitation challenge is to dynamically populate a container with multiple HTML components using actionScript (like, in a VBox).
The XML that I was using had a tag which contained HTML. I was fortunate enough to be able to parse the HTML-inside-the-XML and divide it into several chunks by using ”
” as a delimiter:
private function createHTML():void { //rss is the XML from the feed //currentItem is the current entry within the feed being displayed var content:String = String(rss.item[currentItem].content); //by putting the delimiter in parenthesis ( ), it is appended to the array var array:Array = content.split(/()/); var html:HTML; for (var i:uint; i < array.length; i ++) { html = new HTML(); html.width = this.width; html.htmlText = array[i]; this.addChild(html); } }
When you change the XML feed or change currentItem, you’ll need to remove the the HTML components (firstly setting their content to null), and also the XML feed. Thanks to Greg Wilson’s Ramblings on garbage collection.
private function clearHTML():void { var html:HTML; for (var i:uint; i < this.numChildren; i++) { if (this.getChildAt(i) is HTML) { html = HTML(this.getChildAt(i)); html.htmlText = ""; //set the content to null } } this.removeAllChildren(); }
Before loading any other xml feeds, do this first:
System.disposeXML(rss);
I don’t advise passing the XML down to nested components, because of the way AIR prepares XML for garbage collection (as in, it doesn’t).
Instead, convert what you need to a string or array or arrayCollection, and pass that down to nested components. I do this right away and System.disposeXML(rss) immediately afterwards. For this same reason, I would avoid binding for a project like this. MXML and binding are super fast ways to develop, but in this case, the garbage collection is a bigger issue.
After all that, if the app’s memory usage still grows, you can follow Sean Christmann’s advice (from Craftymind) here.