Developing Android Applications with Adobe AIR [114]
var sprite:Sprite = new Sprite();
// strongly referenced listeners
sprite.addEventListener(MouseEvent.CLICK, onClick);
// weakly referenced listeners
// eventName, listener, capturePhase, priority, useWeakReference
sprite.addEventListener(MouseEvent.CLICK, onClick, false, 1, true);
Use this approach with caution. Too many developers tend to rely on it instead of removing listeners in code. As a responsible coder, you should be diligent about doing the proper housekeeping.
If your code is large, or difficult to maintain, you can create an array to store listeners or a mechanic to automate their removal.
Create a destroy method to use in your classes to remove listeners and objects. To enforce the practice, use an IDestroy interface in which all classes need to have the destroy method but can implement it according to their individual needs:
// interface
public interface IDestroy {
function destroy():void;
}
// class A
public class ClassA implements IDestroy {
public function ClassA() {
}
public function destroy():void {
// remove listeners
// clear display list
while (numChildren > 0) {
removeChildAt(0);
}
}
}
// class B
public class ClassB implements IDestroy {
public function ClassB() {
}
public function destroy(event:):void {
// empty arrays
// set variables to null
// call garbage collection
System.gc();
}
}
If one of your classes implements the interface but erroneously does not have a destroy method, you will see the following error:
Interface method destroy in namespace com:IDestroy not implemented by class
com.ClassC
Garbage Collection
Garbage collection is an automatic mechanism that deallocates the memory used by objects when they are no longer referenced in the application. It is important because it releases memory for future use, and particularly so for mobile devices with limited memory.
The garbage collector is not predictable, but you can sometimes monitor it by watching your memory consumption using the System class. totalMemory refers to the portion of memory allocated to your code. privateMemory is the entire memory consumption of the application. All functions return bytes; divide by 1,024 to obtain kilobytes:
import flash.system.System;
System.privateMemory/1024;
System.totalMemory/1024;
System.totalMemoryNumber/1024 // returned as NUMBER for greater precision
System.freeMemory/1024; // memory unused
You can call the garbage collector directly in AIR, but it requires significant memory and can result in a noticeable slowdown in the application. For this reason, reuse objects or clean them up quickly and frequently as described earlier:
System.gc();
The AIR runtime uses two different methods for best results.
Reference count keeps track of the object and marks it for deletion when it has a value of zero if it has no reference:
var a:Object = new Object(); count is 1 for a;
var b:Object = a; 2 for b;
a = null; 1 for a;
b = null; 0 for b;
This method fails when two objects reference each another:
var a:Object = new Object(); is 1 for a;
var b:Object = new Object(); is 1 for b;
a.b = b; 2 for b;
b.a = a; 2 for a;
a = null; 1 for a;
b = null; 1 for b;
Mark sweeping handles this issue in a more accurate way but takes longer and does not happen as often. It traverses the entire application tree and marks an object that has a reference, marks its children, and so on, recursively. Objects that are not marked can be assumed to be eligible for collection.
In AIR for Android, the garbage collector is more iterative and objects are collected more frequently because memory is in short supply. For this reason, be attentive to making sensors and objects with listener member variables, not local variables.
Events
EventDispatcher is the base class for all objects that can be a target for events. Many native classes inherit from this class with their own appropriate events:
import flash.display.Sprite;
import flash.events.MouseEvent;
// this draws a button listening