Titanium JIRA Archive
Titanium SDK/CLI (TIMOB)

[TIMOB-7505] Android: event listener added in another event listener is not removed

GitHub Issuen/a
TypeBug
PriorityLow
StatusOpen
ResolutionUnresolved
Affected Version/sRelease 1.8.0.1
Fix Version/sn/a
ComponentsAndroid
Labelsn/a
ReporterAdam Wallner
AssigneeIngo Muschenetz
Created2012-01-29T22:51:37.000+0000
Updated2015-04-13T20:12:14.000+0000

Description

Problem

addEventListener in another event listener is not removed by removeEventListener.

Test Case

Every time the button is clicked, one extra "blurListener" is added, each resulting in a message on log. Thus, the removeEventListener is not working.
Ti.UI.setBackgroundColor('#000');

var win1 = Ti.UI.createWindow({
	title: 'Win1',
	fullscreen: true
});

var win2 = Ti.UI.createWindow({
	title: 'Win2',
	fullscreen: true
});

var btn = Ti.UI.createButton({
	title: 'Button',
	top: 10
});
win1.add(btn);

var lbl = Ti.UI.createLabel({
	text: 'Label',
	top: 10
});
win2.add(lbl);

var i = 0;
var blurListener = function() {
	Ti.API.info('blurListener: ' + (i++));
	win1.removeEventListener('blur', blurListener);
};

btn.addEventListener('click', function() {
	win1.addEventListener('blur', blurListener);	
	
	Ti.API.info('---');
	win2.open({
		animated: true
	});
});

win1.open();

Workaround

You can solve the problem by overriding the addEventListener and removeEventListener prototypes of the Titanium.UI.Window objects. Just insert the code below into the app.js.
(function() {
	if (Ti.Platform.name == 'android') {
		var _addEventListener = Ti.UI.Window.prototype.addEventListener;
		var _removeEventListener = Ti.UI.Window.prototype.removeEventListener;
		
		Ti.UI.Window.prototype._eventListener = function(e) {
			if (typeof e.source == 'undefined') return;
			if (e.source.toString() != '[object TiBaseWindow]') return;
			var listeners = e.source._eventListeners[e.type];
			for (var i=0; i<listeners.length; i++)
				listeners[i](e);
		};
		
		Ti.UI.Window.prototype.addEventListener = function(type, func) {
			if (!this._eventListeners) this._eventListeners = {};
			if (typeof this._eventListeners[type] == 'undefined') {
				this._eventListeners[type] = [];
				_addEventListener.call(this, type, this._eventListener);	
			}
			this._eventListeners[type].push(func);
		};
		
		Ti.UI.Window.prototype.removeEventListener = function(type, func) {
			if (typeof this._eventListeners[type] != 'undefined') {
				var listeners = this._eventListeners[type];
				for (var i=0; i<listeners.length; i++) {
					listeners.splice(i, 1);
					break;	
				}
			}
		};
	}
})();

Logs

The output of the above script after 3 button press and back:
[INFO]	---
[INFO]	blurListener: 0
[INFO]	---
[INFO]	blurListener: 1
[INFO]	blurListener: 2
[INFO]	---
[INFO]	blurListener: 3
[INFO]	blurListener: 4
[INFO]	blurListener: 5

Comments

  1. Paul Dowsett 2012-01-30

    Thanks for raising this ticket. Would you please do the following to allow it to be escalated: * to the environment field, add the runtime this has been tested with * add the logs that shows what happened when the test case was launched Please review the [JIRA Ticket Checklist](https://wiki.appcelerator.org/display/guides/How+to+Submit+a+Bug+Report#HowtoSubmitaBugReport-JIRATicketChecklist) when raising tickets, and start all tickets using the [JIRA Ticket Template](https://wiki.appcelerator.org/display/guides/JIRA+Ticket+Template). Many thanks
  2. Adam Wallner 2012-01-31

    I've changed the report. I've made a better example and workaround. Thanks
  3. Paul Dowsett 2012-01-31

    Adam To the environment field, please state the runtime which has exhibited this issue - v8 or rhino. Thanks
  4. Adam Wallner 2012-01-31

    Oh, it's the V8 engine, sorry. I've not tested on Rhino.

JSON Source