{ "id": "63193", "key": "TIMOB-2561", "fields": { "issuetype": { "id": "1", "description": "A problem which impairs or prevents the functions of the product.", "name": "Bug", "subtask": false }, "project": { "id": "10153", "key": "TIMOB", "name": "Titanium SDK/CLI", "projectCategory": { "id": "10100", "description": "Titanium and related SDKs used in application development", "name": "Client" } }, "fixVersions": [ { "id": "11244", "name": "Release 1.7.0", "archived": true, "released": true, "releaseDate": "2011-06-13" }, { "id": "11245", "name": "Sprint 2011-10", "archived": true, "released": true, "releaseDate": "2011-03-14" } ], "resolution": { "id": "7", "description": "", "name": "Invalid" }, "resolutiondate": "2011-04-26T09:04:11.000+0000", "created": "2011-04-15T03:22:49.000+0000", "priority": { "name": "Trivial", "id": "5" }, "labels": [ "android", "defect", "enterprise", "httpclient", "release-1.7.0", "rplist" ], "versions": [], "issuelinks": [], "assignee": { "name": "dthorp", "key": "dthorp", "displayName": "Don Thorp", "active": true, "timeZone": "America/Los_Angeles" }, "updated": "2011-12-23T08:52:01.000+0000", "status": { "description": "The issue is considered finished, the resolution is correct. Issues which are closed can be reopened.", "name": "Closed", "id": "6", "statusCategory": { "id": 3, "key": "done", "colorName": "green", "name": "Done" } }, "components": [ { "id": "10202", "name": "Android", "description": "Android Platform" } ], "description": "{html}
I am getting the following error when a function calling a\nTi.Network.createHTTPClient() -> send() is invoked a second\ntime. First time it works well and good
\nWARN/MessageQueue(367): Handler{43f82b30} sending message to a\nHandler on a dead thread
\njava.lang.RuntimeException: Handler{43f82b30} sending message to a\nHandler on a dead thread
\nat android.os.MessageQueue.enqueueMessage(MessageQueue.java:179)\nat android.os.Handler.sendMessageAtTime(Handler.java:457)\nat android.os.Handler.sendMessageDelayed(Handler.java:430)\nat android.os.Handler.post(Handler.java:248)\nat org.appcelerator.titanium.kroll.KrollContext.post(KrollContext.java:123)\nat org.appcelerator.titanium.kroll.KrollCallback.callAsync(KrollCallback.java:154)\nat org.appcelerator.titanium.kroll.KrollCallback.callAsync(KrollCallback.java:89)\nat org.appcelerator.titanium.kroll.KrollCallback.callAsync(KrollCallback.java:84)\nat ti.modules.titanium.network.TiHTTPClient.fireCallback(TiHTTPClient.java:468)\nat ti.modules.titanium.network.TiHTTPClient.fireCallback(TiHTTPClient.java:459)\nat ti.modules.titanium.network.TiHTTPClient.setReadyState(TiHTTPClient.java:491)\nat ti.modules.titanium.network.TiHTTPClient$ClientRunnable.run(TiHTTPClient.java:989)\nat java.lang.Thread.run(Thread.java:1096)
\n
Some more info:
\nthis happens when I have something like this
\nfrmNewBoard.addEventListener('close', function(e)
\n{\n loadBoardsFromNetwork(); // it fails in this function\n});\nfrmNewBoard.open(\n{\n});
\n
\ni.e. the network request works fine when a Window is loaded, the\nwindow then loads another window frmNewBoard on a button click. I\nhave added an event to listen for frmBewBoard closing, and calling\nthe network request. The error message above is what i get when\nthis second network request is sent.
\nThanks
Is someone even listening to this thread to help identify the\nissue?
\nAnyhow, I have some further info.
\nThis problem only occurs when the network request is called from\n'close' event
frmNewBoard.addEventListener('close', function(e)
\n{
\n loadBoardsFromNetwork(); // it fails in this function
\n
\n}); frmNewBoard.open(
\n{ });
However it works if I call a button click event which load the\nboard like this
\nbutton.addEventListener('close', function(e)
\n{
\n loadBoardsFromNetwork(); // works now
\n
\n});
\nfrmNewBoard.addEventListener('close', function(e)
\n{ button.fireEvent('click');// it works now });\nfrmNewBoard.open(
\n{ });
So obviously, there is some threading issue with 'close'\nevent
We are facing exactly the same problem after upgrading to 1.5.0\non Android. We add an event listener for the 'close' event on a\nwindow. In the event handler, we make a network call which is\nfailing with the same exception. This used to work fine on\n1.4.x.
\nWe will try out Ravi's workaround in the meanwhile and update\nthis ticket with our results. Thanks Ravi.
Can you please include a boiled down test app that we can use to\nreproduce the behavior?
\nThanks
\nOpie
seems to be related to whether you open the window as modal or\nnot, then drop back to the main window. When I tried it with a\nmodal window, the returning 'close' event and subsequent xhr\nrequest did not work. When I switched it to a normal window, it DID\nwork - the rest of the code being the same in either case.
\ngo figure!
\nDavid
I was able to reproduce the same error using the following code.\nNote that it's a very sensitive bit of code... if you remove pretty\nmuch anything from the source below, the exception won't get hit.\nIt was rather excruciating to recreate, actually.
\n\nvar tabGroup = Titanium.UI.createTabGroup();\nvar win = Ti.UI.createWindow();\nvar tab = Titanium.UI.createTab({ title:'HTTP Exception Reproducer', window:win });\ntabGroup.addTab(tab);\ntabGroup.open();\n\nvar detailWin = Ti.UI.createWindow();\nvar xhr = Ti.Network.createHTTPClient({'timeout' : 25000});\nxhr.onload = function() {\n var db = Ti.UI.createButton({ width:250, height:100, title:'Now Touch Me.'});\n db.addEventListener('click', function() {\n var dialog = Titanium.UI.createOptionDialog({\n options:['Do It'],\n title:'Finally, touch \"Do It\".'\n });\n dialog.addEventListener('click', function() {\n var xhr = Ti.Network.createHTTPClient({'timeout' : 25000});\n xhr.onload = function() {\n var xhr = Ti.Network.createHTTPClient({'timeout' : 25000});\n xhr.onload = function() {\n };\n xhr.open('POST', 'http://a17g.com');\n xhr.send({'method':'get_entry_list', 'input_type':'JSON','response_type':'JSON','rest_data':'asdf'});\n detailWin.close();\n };\n xhr.open('POST', 'http://a17g.com');\n xhr.send();\n });\n dialog.show();\n });\n detailWin.add(db);\n tab.open(detailWin);\n};\nxhr.open('POST', 'http://a17g.com');\nxhr.send();
\n
\n\n[TRACE] D/TiHttpClient( 801): (TiHttpClient-3) [451,41308] Setting ready state to 2\n[TRACE] D/TiHttpClient( 801): (TiHttpClient-3) [1,41309] Setting ready state to 3\n[TRACE] D/TiHttpClient( 801): (TiHttpClient-3) [85,41394] Setting ready state to 4\n[TRACE] W/MessageQueue( 801): Handler{45055658} sending message to a Handler on a dead thread\n[TRACE] W/MessageQueue( 801): java.lang.RuntimeException: Handler{45055658} sending message to a Handler on a dead thread\n[TRACE] W/MessageQueue( 801): at android.os.MessageQueue.enqueueMessage(MessageQueue.java:179)\n[TRACE] W/MessageQueue( 801): at android.os.Handler.sendMessageAtTime(Handler.java:457)\n[TRACE] W/MessageQueue( 801): at android.os.Handler.sendMessageDelayed(Handler.java:430)\n[TRACE] W/MessageQueue( 801): at android.os.Handler.post(Handler.java:248)\n[TRACE] W/MessageQueue( 801): at org.appcelerator.titanium.kroll.KrollContext.post(KrollContext.java:125)\n[TRACE] W/MessageQueue( 801): at org.appcelerator.titanium.kroll.KrollCallback.callAsync(KrollCallback.java:161)\n[TRACE] W/MessageQueue( 801): at org.appcelerator.titanium.kroll.KrollCallback.callAsync(KrollCallback.java:96)\n[TRACE] W/MessageQueue( 801): at org.appcelerator.titanium.kroll.KrollCallback.callAsync(KrollCallback.java:91)\n[TRACE] W/MessageQueue( 801): at ti.modules.titanium.network.TiHTTPClient.fireCallback(TiHTTPClient.java:477)\n[TRACE] W/MessageQueue( 801): at ti.modules.titanium.network.TiHTTPClient.fireCallback(TiHTTPClient.java:468)\n[TRACE] W/MessageQueue( 801): at ti.modules.titanium.network.TiHTTPClient.setReadyState(TiHTTPClient.java:500)\n[TRACE] W/MessageQueue( 801): at ti.modules.titanium.network.TiHTTPClient$ClientRunnable.run(TiHTTPClient.java:1017)\n[TRACE] W/MessageQueue( 801): at java.lang.Thread.run(Thread.java:1096)
\n
\nTitanium Mobile SDK 1.6.0 1/19/11 13:13
\nAndroid Simulator 2.2
Any chance we can bump the priority of this up to high? It's\ncausing our app to crash in numerous places. Thanks!
This behavior is actually due to the containing context for the\nhttpclient object being destroyed before the request finishes\nexecuting. In the above example, the httpclient that contains the\ncallbacks for the request is already destroyed before all the\nupdates fire and thus an exception is generated. In short, there is\na race condition between the send call and the close.
\nIn order to get around this, the close should be called from the\nonload callback for the request. In general, any operations that a\nre dependent on network requests should be event / callback driven\nsince you can not relay on network requests happening in a timely\nfashion. I have provided a modified version of the previous example\ncode.
\n\nvar tabGroup = Titanium.UI.createTabGroup();\nvar win = Ti.UI.createWindow();\nvar tab = Titanium.UI.createTab({ title:'HTTP Exception Reproducer', window:win });\ntabGroup.addTab(tab);\ntabGroup.open();\n\nvar detailWin = Ti.UI.createWindow();\nvar xhr = Ti.Network.createHTTPClient({'timeout' : 25000});\nxhr.onload = function() {\n var db = Ti.UI.createButton({ width:250, height:100, title:'Now Touch Me.'});\n db.addEventListener('click', function() {\n var dialog = Titanium.UI.createOptionDialog({\n options:['Do It'],\n title:'Finally, touch \"Do It\".'\n });\n dialog.addEventListener('click', function() {\n var xhr = Ti.Network.createHTTPClient({'timeout' : 25000});\n xhr.onload = function() {\n var xhr = Ti.Network.createHTTPClient({'timeout' : 25000});\n xhr.onload = function() {\n Ti.API.info(\"closing window\");\n detailWin.close();\n };\n xhr.open('POST', 'http://a17g.com');\n xhr.send({'method':'get_entry_list', 'input_type':'JSON','response_type':'JSON','rest_data':'asdf'});\n };\n xhr.open('POST', 'http://a17g.com');\n xhr.send();\n });\n dialog.show();\n });\n detailWin.add(db);\n tab.open(detailWin);\n};\nxhr.open('POST', 'http://a17g.com');\nxhr.send();
\n
Opie, thanks for looking into this, we have already re-worked\nour code base to incorporate the necessary changes. I guess my only\ncomment is that the code referenced previously does work with the\niphone implementation and as an end user I really shouldn't have to\ncare about the implementation limitations for droid. The\ninconsistency between the platforms will probably end up biting\nsome users trying to port their apps over.