Titanium JIRA Archive
Titanium SDK/CLI (TIMOB)

[TIMOB-17704] iOS: XHR onreadystatechange called multiple times

GitHub Issuen/a
TypeBug
PriorityCritical
StatusClosed
ResolutionFixed
Resolution Date2014-10-22T21:17:56.000+0000
Affected Version/sn/a
Fix Version/sRelease 3.4.2, Release 3.5.0, Release 4.0.0
ComponentsiOS
LabelsRelease-3.4.0, TCSupportTriage, ios, module_network, qe-manualtest, release-3.3, release-3.4.0
ReporterDonovan Lewis
AssigneeVishal Duggal
Created2014-09-09T15:40:15.000+0000
Updated2014-11-24T23:51:17.000+0000

Description

When using a XHR createHTTPClient the onreadystatechange is called multiple times. This mostly seems to happen on readystate 4. If your app uses a lot of XHR threads this will cause the app to hang and crash. Log from test app: {quote} [DEBUG] Application booted in 62.319040 ms [INFO] readystate: 1 [INFO] readystate: 4 [INFO] size 104874307 [INFO] readystate: 4 [INFO] size 104874307 {quote} Test app:
var win = Ti.UI.createWindow({title: 'Demo', tabBarHidden: true, backgroundColor: '#fff'});

var button = Titanium.UI.createButton({
   title: 'Start',
   top: 10,
   width: 100,
   height: 50
});

win.add(button);

function getSize() {
    
		var self = this,
	    xhr = Ti.Network.createHTTPClient({
	    timeout: this.timeout,

		    onreadystatechange: function (e) {
		    	Titanium.API.info("readystate: " + this.readyState);
		        if (this.readyState === this.DONE) {
		            Titanium.API.info('size ' + parseInt(this.getResponseHeader('Content-Length')));

		        }
		    },

		    onerror: function (e) {
		        
		    }
		});
		xhr.open('HEAD', 'http://speedtest.dal05.softlayer.com/downloads/test100.zip');
		xhr.send();
}

button.addEventListener('click',function(e)
{
   getSize();
});

win.open();

Comments

  1. Vishal Duggal 2014-10-16

    Test Case
       var win = Ti.UI.createWindow({title: 'Demo', tabBarHidden: true, backgroundColor: '#fff'});
        
       var button = Titanium.UI.createButton({
          title: 'Start',
          top: 10,
          width: 100,
          height: 50
       });
        
       win.add(button);
        
       function getSize() {
            
               var self = this,
               xhr = Ti.Network.createHTTPClient({
               timeout: this.timeout,
        
                   onreadystatechange: function (e) {
                       if (e.readyState) {
                           Titanium.API.info('Event readystate: ' + e.readyState+' Object readyState: '+this.readyState);
                           if (e.readyState === this.DONE) {
                               Titanium.API.info('size ' + parseInt(this.getResponseHeader('Content-Length'))); 
                           }
                       } else {
                           Titanium.API.info("readystate: " + this.readyState);
                           if (this.readyState === this.DONE) {
                               Titanium.API.info('size ' + parseInt(this.getResponseHeader('Content-Length')));
                           }
                       }
                   },
        
                   onerror: function (e) {
                        
                   }
               });
               xhr.open('HEAD', 'http://speedtest.dal05.softlayer.com/downloads/test100.zip');
               xhr.send();
       }
        
       button.addEventListener('click',function(e)
       {
          getSize();
       });
        
       win.open();
       
  2. Vishal Duggal 2014-10-16

    Pull pending master - https://github.com/appcelerator/titanium_mobile/pull/6228 3_4_X - https://github.com/appcelerator/titanium_mobile/pull/6229
  3. Ewan Harris 2014-11-24

    Verified fix on: Mac OSX 10.10.1 Appcelerator Studio, build: 3.4.1.201410281743 Titanium SDK build: 3.5.0.v20141124092514, 3.6.0.v20141124111716 Titanium CLI, build: 3.4.1 Alloy: 1.5.1 Xcode 6.1.1 GM Seed iPhone 6 Plus (8.1) Nexus 6 (5.0) Using the test code above ran on both devices and the output is as expected. The readyState property for the event, e, is always unique. On Android the app no longer crashes and it runs as expected.

JSON Source