{ "id": "63065", "key": "TIMOB-2433", "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": "11237", "name": "Release 1.6.0 M04", "archived": true, "released": true, "releaseDate": "2011-01-10" } ], "resolution": { "id": "1", "description": "A fix for this issue is checked into the tree and tested.", "name": "Fixed" }, "resolutiondate": "2011-04-17T01:59:05.000+0000", "created": "2011-04-15T03:19:40.000+0000", "priority": { "name": "Low", "id": "4" }, "labels": [ "android", "click", "defect", "enterprise", "menuitem", "optionmenu", "release-1.6.0", "rplist" ], "versions": [], "issuelinks": [], "assignee": { "name": "dthorp", "key": "dthorp", "displayName": "Don Thorp", "active": true, "timeZone": "America/Los_Angeles" }, "updated": "2011-04-17T01:59:05.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 have an app with 4 tabs. One of the tabs has a OptionMenu\nassociated with it with a few MenuItems. When I initially go to the\ntab, I can properly call up the menu and touching each item invokes\nits click callback, as should be expected. However, if I switch off\nof that window (either by changing tabs, or launching a child\nwindow in that same tab), and then come back, the menu will\n(usually) still pop up, but the menuitems won't trigger (I can\ntouch the item, but click never gets called).

\n

I have tested this same exact code under 1.4.2 with Android and\niOS and it works properly. This seems like a 1.5.x regression\n(using the 1.5.x from 11/24).

{html}", "attachment": [ { "id": "18148", "filename": "ticket2433.zip", "author": { "name": "opiecyrus", "key": "opiecyrus", "displayName": "Opie Cyrus", "active": true, "timeZone": "America/Chicago" }, "created": "2011-04-15T03:19:41.000+0000", "size": 4203970, "mimeType": "application/zip" } ], "flagged": false, "summary": "Android: OptionMenu MenuItem's click callbacks don't persist w/ tabbed window switching", "creator": { "name": "robby", "key": "robby", "displayName": "Robby", "active": true, "timeZone": "America/Los_Angeles" }, "subtasks": [], "reporter": { "name": "robby", "key": "robby", "displayName": "Robby", "active": true, "timeZone": "America/Los_Angeles" }, "environment": null, "comment": { "comments": [ { "id": "128448", "author": { "name": "dthorp", "key": "dthorp", "displayName": "Don Thorp", "active": true, "timeZone": "America/Los_Angeles" }, "body": "{html}

Robby, I'm going to be changing the menu API for 1.5 this\nweekend if I can get it finished. It would be a great help if you\ncould attach a non-proprietary test case that I can use to verify\nwhat you're seeing now. The underlying problem is a menu is\ndirectly tied to an Android Activity and in 1.4.X and earlier it's\nalmost impossible to always guess the correct one. In 1.5.X menu\nwill move to Ti.Android.currentActivity so that it's always\nassociated with the correct one.

{html}", "updateAuthor": { "name": "dthorp", "key": "dthorp", "displayName": "Don Thorp", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2011-04-15T03:19:42.000+0000", "updated": "2011-04-15T03:19:42.000+0000" }, { "id": "128449", "author": { "name": "robby", "key": "robby", "displayName": "Robby", "active": true, "timeZone": "America/Los_Angeles" }, "body": "{html}

Don, this is a tough one to reproduce. I spent some time on\ndeveloping a test case but they worked rather consistently. I then\ntook my code and tried to chip away at it until I could identify\nthe problem. The code I have constructs a tableview, search bar,\nthen makes a HTTP request. After the HTTP request returns, it calls\na function that puts several labels and a view (a notification\ncircle) on each tableviewrow object, then calls setData on the\ntableview. Rather direct, and it works in Android 1.4 and on iOS\nfine, but I need 1.5.x as I have a few custom Android modules.

\n

The problem I'm actually seeing with that window is that the\nmenu button normally doesn't work at all (that, or sometimes it\nwill work, but the onclick handlers for the children wont). By\nselectively removing parts, it would seem to be somewhat of a race\ncondition: If I keep everything but the rendering of the labels, it\nworks fine, every time. Then, I try something like the following\n(I'm rendering 3 labels and a view on each tableview row\noverall):

\n

Render label 1: works
\nrender label 2: works
\nrender view and label 3: works
\nrender label 1 & 2: works
\nrender label 1 & 3, and view: works
\nrender label 1 & 3, and view: works
\nrender label 1, 2, 3, and view: fails (rendering appears fine, but\nthe menu button doesn't work)

\n

So the elements render alone fine, but if I try ALL of them, it\nfails. I have my debug up to trace, and all I see is:

\n

error: [TRACE] W/InputManagerService( 61): Window\nalready focused, ignoring focus gain of:\ncom.android.internal.view.IInputMethodClient$Stub$Proxy@45065610

\n

When I try to press the menu button.

\n

Again, this works fine on 1.4 (just tested it now again on the\n1.4 build from Oct 15th).... I can send you the relevant\nproprietary code if needed. I'm also available to speak more on\nthis over Lighthouse or the phone as well. I can't seem to find a\nworkaround to this either, and can't do the initial release on\nAndroid until the menus work unfortunately, so I'm your man on this\nissue :).

\n

If you're planning a redesign of the 1.5 menu system, it may be\nbest to just move forward with that and see if that magically fixes\nthe problem. There's a very good chance it would. I've been running\ninto plenty of menu weirdness in 1.5 under Android.

\n

1.4.2 where it works: version=1.4.2 timestamp=10/11/10 19:02\ngithash=425bc37
\n1.5 where it fails: version=1.5.0 timestamp=11/24/10 04:54\ngithash=c0aff27

\n

This is under Windows 7 64bit.

{html}", "updateAuthor": { "name": "robby", "key": "robby", "displayName": "Robby", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2011-04-15T03:19:42.000+0000", "updated": "2011-04-15T03:19:42.000+0000" }, { "id": "128450", "author": { "name": "robby", "key": "robby", "displayName": "Robby", "active": true, "timeZone": "America/Los_Angeles" }, "body": "{html}

Oops, meant to say the 1.4.2 build from Oct 11th, not the\n15th.

{html}", "updateAuthor": { "name": "robby", "key": "robby", "displayName": "Robby", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2011-04-15T03:19:42.000+0000", "updated": "2011-04-15T03:19:42.000+0000" }, { "id": "128451", "author": { "name": "dthorp", "key": "dthorp", "displayName": "Don Thorp", "active": true, "timeZone": "America/Los_Angeles" }, "body": "{html}

Robby, do you have a sample I can test with. I want to verify\nthis works with the new menu code.

{html}", "updateAuthor": { "name": "dthorp", "key": "dthorp", "displayName": "Don Thorp", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2011-04-15T03:19:43.000+0000", "updated": "2011-04-15T03:19:43.000+0000" }, { "id": "128452", "author": { "name": "robby", "key": "robby", "displayName": "Robby", "active": true, "timeZone": "America/Los_Angeles" }, "body": "{html}

Hi Don,

\n

I migrated to the new code based off of android activities,\nusing the commit you made as an example. Looks very promising so\nfar. A few issues:

\n
    \n
  1. \n

    In the menu callbacks, I had an alert() statement to test.\nBefore this migration, I used to get an alert box pop up, now the\ntext is printed to the console without the box popping up (just\nlike would have happened if I had done Ti.API.info()). Is this a\nbug?

    \n
  2. \n
  3. \n

    I believe you have a bug in your menu.add() code similar to\n#274.\nI have code in one of my windows that adds to the menu from a\nxhr.onload callback (i.e. not the UI thread), and I get:

    \n
  4. \n
\n
\n[TRACE] E/KrollCallback( 472): (kroll$5) [262,145110] Error evaluating source, invocation: [callMethod Network.HTTPClient.(anonymous) org.appcelerator.titanium.kroll.KrollCallback@452efb28], message: Wrapped android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views. (app://win_games.js#797)\n[TRACE] E/KrollCallback( 472): org.mozilla.javascript.WrappedException: Wrapped android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views. (app://win_games.js#797)\n[TRACE] E/KrollCallback( 472): at org.mozilla.javascript.Context.throwAsScriptRuntimeEx(Context.java:1781)\n[TRACE] E/KrollCallback( 472): at org.appcelerator.kroll.KrollMethod.call(KrollMethod.java:77)\n[TRACE] E/KrollCallback( 472): at org.mozilla.javascript.Interpreter.interpretLoop(Interpreter.java:1711)\n[TRACE] E/KrollCallback( 472): at script(app://win_games.js:797)\n[TRACE] E/KrollCallback( 472): at script(file:///android_asset/Resources/shared.js:413)\n[TRACE] E/KrollCallback( 472): at org.mozilla.javascript.Interpreter.interpret(Interpreter.java:854)\n[TRACE] E/KrollCallback( 472): at org.mozilla.javascript.InterpretedFunction.call(InterpretedFunction.java:164)\n[TRACE] E/KrollCallback( 472): at org.mozilla.javascript.ContextFactory.doTopCall(ContextFactory.java:426)\n[TRACE] E/KrollCallback( 472): at org.mozilla.javascript.ScriptRuntime.doTopCall(ScriptRuntime.java:3161)\n[TRACE] E/KrollCallback( 472): at org.mozilla.javascript.InterpretedFunction.call(InterpretedFunction.java:162)\n[TRACE] E/KrollCallback( 472): at org.appcelerator.titanium.kroll.KrollCallback.callSync(KrollCallback.java:109)\n[TRACE] E/KrollCallback( 472): at org.appcelerator.titanium.kroll.KrollCallback$1.run(KrollCallback.java:133)\n[TRACE] E/KrollCallback( 472): at android.os.Handler.handleCallback(Handler.java:587)\n[TRACE] E/KrollCallback( 472): at android.os.Handler.dispatchMessage(Handler.java:92)\n[TRACE] E/KrollCallback( 472): at android.os.Looper.loop(Looper.java:123)\n[TRACE] E/KrollCallback( 472): at org.appcelerator.titanium.kroll.KrollHandlerThread.run(KrollHandlerThread.java:73)\n[TRACE] E/KrollCallback( 472): Caused by: android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.\n[TRACE] E/KrollCallback( 472): at android.view.ViewRoot.checkThread(ViewRoot.java:2802)\n[TRACE] E/KrollCallback( 472): at android.view.ViewRoot.requestLayout(ViewRoot.java:594)\n[TRACE] E/KrollCallback( 472): at android.view.View.requestLayout(View.java:8125)\n[TRACE] E/KrollCallback( 472): at android.view.View.requestLayout(View.java:8125)\n[TRACE] E/KrollCallback( 472): at android.view.ViewGroup.removeAllViews(ViewGroup.java:2255)\n[TRACE] E/KrollCallback( 472): at com.android.internal.view.menu.IconMenuView.updateChildren(IconMenuView.java:338)\n[TRACE] E/KrollCallback( 472): at com.android.internal.view.menu.MenuBuilder.onItemsChanged(MenuBuilder.java:908)\n[TRACE] E/KrollCallback( 472): at com.android.internal.view.menu.MenuBuilder.addInternal(MenuBuilder.java:379)\n[TRACE] E/KrollCallback( 472): at com.android.internal.view.menu.MenuBuilder.add(MenuBuilder.java:393)\n[TRACE] E/KrollCallback( 472): at org.appcelerator.titanium.proxy.MenuProxy.add(MenuProxy.java:64)\n[TRACE] E/KrollCallback( 472): at org.appcelerator.titanium.proxy.MenuProxyBindingGen$6.invoke(MenuProxyBindingGen.java:264)\n[TRACE] E/KrollCallback( 472): at org.appcelerator.kroll.KrollMethod.call(KrollMethod.java:46)\n[TRACE] E/KrollCallback( 472): ... 12 more\n
\n

Besides those issues, menu loading and functionality SEEM to be\nmuch improved!! Let me know if you address these issues and I'll\ngive her another go.

\n

Robby

{html}", "updateAuthor": { "name": "robby", "key": "robby", "displayName": "Robby", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2011-04-15T03:19:43.000+0000", "updated": "2011-04-15T03:19:43.000+0000" }, { "id": "128453", "author": { "name": "dthorp", "key": "dthorp", "displayName": "Don Thorp", "active": true, "timeZone": "America/Los_Angeles" }, "body": "{html}

Robby, more changes were pushed. Without and example I can\nverify that this is fixed.

{html}", "updateAuthor": { "name": "dthorp", "key": "dthorp", "displayName": "Don Thorp", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2011-04-15T03:19:43.000+0000", "updated": "2011-04-15T03:19:43.000+0000" }, { "id": "128454", "author": { "name": "robby", "key": "robby", "displayName": "Robby", "active": true, "timeZone": "America/Los_Angeles" }, "body": "{html}

Don,

\n

Just tried it with the nightly from today: version=1.5.0\ntimestamp=12/09/10 01:18 githash=43358e5

\n

Item #1 from above seems to be fixed. Below is a\ntestcase that isolates #2 from above. (I also used it to verify item\n#1 from\nabove was fixed.)

\n
\nTi.API.info(\"@ win_test.js\");\nvar win = Ti.UI.currentWindow;\nwin.backgroundColor = \"#b5aea5\";\n\n\nvar activity = Ti.Android.currentActivity;\nactivity.onCreateOptionsMenu = function(e) {\n  var aMenu = e.menu;\n  var test1 = aMenu.add({\n    title: 'Test1',\n  });\n  test1.addEventListener('click', function() {\n    alert(\"alert: Test1\");\n  });\n  \n  var test2 = aMenu.add({\n    title: 'Test2',\n  });\n  test2.addEventListener('click', function() {\n    alert(\"alert: Test2\");\n    Ti.API.info(\"Ti.API.info: Test2\");\n  });\n  \n  //Now, make a request and add a menu item from a non-UI thread...\n  var request = Ti.Network.createHTTPClient({\n    timeout: 15000 //15 seconds\n  });\n  \n  request.onload = function(e) {\n    Ti.API.info('HTTPClient onload, status: ' + this.status);\n    Ti.API.info(\"Adding additional menu item (this will fail)\");\n    \n    var test3 = aMenu.add({\n      title: 'Test3',\n    });\n    test3.addEventListener('click', function() {\n      alert(\"alert: Test3\");\n    });\n  };\n  \n  var url = \"http://www.google.com/\";\n  Ti.API.info('Making GET call to: ' + url);\n  request.open(\"GET\", url, true);\n  request.send();\n}\n\n\nvar displayName = Ti.UI.createLabel({\n  top: 0,\n  left: 0,\n  font:{fontSize: 20, fontWeight:'bold'},\n  height: 30,\n  width: 320,\n  color:'#000000',\n  text:\"Testing 123\"\n});\nwin.add(displayName);\n
{html}", "updateAuthor": { "name": "robby", "key": "robby", "displayName": "Robby", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2011-04-15T03:19:43.000+0000", "updated": "2011-04-15T03:19:43.000+0000" }, { "id": "128455", "author": { "name": "dthorp", "key": "dthorp", "displayName": "Don Thorp", "active": true, "timeZone": "America/Los_Angeles" }, "body": "{html}

There is a simple workaround and this is really more how it\nshould be done. Since there is an easy workaround, moving out of\nM05. It's not worth the risk. Basically you should modify your menu\nin onPrepareOptionsMenu for the state.

\n
\nTi.API.info(\"@ win_test.js\");\nvar win = Ti.UI.currentWindow;\nwin.backgroundColor = \"#b5aea5\";\n\nvar xhrComplete = false;\n\nvar activity = Ti.Android.currentActivity;\nactivity.onCreateOptionsMenu = function(e) {\n  var aMenu = e.menu;\n  var test1 = aMenu.add({\n    title: 'Test1',\n  });\n  test1.addEventListener('click', function() {\n    alert(\"alert: Test1\");\n  });\n  \n  var test2 = aMenu.add({\n    title: 'Test2',\n  });\n  test2.addEventListener('click', function() {\n    alert(\"alert: Test2\");\n    Ti.API.info(\"Ti.API.info: Test2\");\n  });\n  \n  //Now, make a request and add a menu item from a non-UI thread...\n  var request = Ti.Network.createHTTPClient({\n    timeout: 15000 //15 seconds\n  });\n  \n  request.onload = function(e) {\n    Ti.API.info('HTTPClient onload, status: ' + this.status);\n    Ti.API.info(\"Adding additional menu item (this will fail)\");\n    setTimeout(function() {\n        xhrComplete = true;\n    }, 5000);    \n  };\n  \n  var url = \"http://www.google.com/\";\n  Ti.API.info('Making GET call to: ' + url);\n  request.open(\"GET\", url, true);\n  request.send();\n}\n\nactivity.onPrepareOptionsMenu = function(e) {\n    var aMenu = e.menu;\n    \n    if (aMenu.size() < 3 && xhrComplete) {\n        var test3 = aMenu.add({\n          title: 'Test3',\n         });\n        test3.addEventListener('click', function() {\n          alert(\"alert: Test3\");\n        });\n    }   \n};\n\n\nvar displayName = Ti.UI.createLabel({\n  top: 0,\n  left: 0,\n  font:{fontSize: 20, fontWeight:'bold'},\n  height: 30,\n  width: 320,\n  color:'#000000',\n  text:\"Testing 123\"\n});\nwin.add(displayName)\n
{html}", "updateAuthor": { "name": "dthorp", "key": "dthorp", "displayName": "Don Thorp", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2011-04-15T03:19:44.000+0000", "updated": "2011-04-15T03:19:44.000+0000" }, { "id": "128456", "author": { "name": "robby", "key": "robby", "displayName": "Robby", "active": true, "timeZone": "America/Los_Angeles" }, "body": "{html}

Great, thanks Don! I'll give this a try this weekend and let you\nknow how it works out.

\n

The new menu system seems to work much better!

{html}", "updateAuthor": { "name": "robby", "key": "robby", "displayName": "Robby", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2011-04-15T03:19:44.000+0000", "updated": "2011-04-15T03:19:44.000+0000" }, { "id": "128457", "author": { "name": "dthorp", "key": "dthorp", "displayName": "Don Thorp", "active": true, "timeZone": "America/Los_Angeles" }, "body": "{html}

Was put in wrong bucket during move from 1.5.1.

{html}", "updateAuthor": { "name": "dthorp", "key": "dthorp", "displayName": "Don Thorp", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2011-04-15T03:19:44.000+0000", "updated": "2011-04-15T03:19:44.000+0000" }, { "id": "128458", "author": { "name": "dthorp", "key": "dthorp", "displayName": "Don Thorp", "active": true, "timeZone": "America/Los_Angeles" }, "body": "{html}

Please triage.

{html}", "updateAuthor": { "name": "dthorp", "key": "dthorp", "displayName": "Don Thorp", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2011-04-15T03:19:45.000+0000", "updated": "2011-04-15T03:19:45.000+0000" }, { "id": "128459", "author": { "name": "opiecyrus", "key": "opiecyrus", "displayName": "Opie Cyrus", "active": true, "timeZone": "America/Chicago" }, "body": "{html}

(from [f4238600ef496a4059347f3c5208bae27ed5427a])\n[#2433 state:fixed-in-qa] Modify MenuProxy kroll\ncalls to run on UI thread

\n

Modified MenuProxy to have all Kroll calls that modify the menu\nexecute on the UI thread and resolve the \"Only the original thread\nthat created a view hierarchy can touch its views\" error.
\n\nhttps://github.com/appcelerator/titanium_mobile/commit/f4238600ef49...

{html}", "updateAuthor": { "name": "opiecyrus", "key": "opiecyrus", "displayName": "Opie Cyrus", "active": true, "timeZone": "America/Chicago" }, "created": "2011-04-15T03:19:46.000+0000", "updated": "2011-04-15T03:19:46.000+0000" }, { "id": "128460", "author": { "name": "opiecyrus", "key": "opiecyrus", "displayName": "Opie Cyrus", "active": true, "timeZone": "America/Chicago" }, "body": "{html}

Please test the fix with the attached test app. This is\nbasically the pasted code above from Robby.

\n

1) Click \"open window\"
\n2) Launch the menu and you should see 3 tabs shown in the menu.

\n

Thanks
\nOpie

{html}", "updateAuthor": { "name": "opiecyrus", "key": "opiecyrus", "displayName": "Opie Cyrus", "active": true, "timeZone": "America/Chicago" }, "created": "2011-04-15T03:19:46.000+0000", "updated": "2011-04-15T03:19:46.000+0000" }, { "id": "128461", "author": { "name": "thomashuelbert", "key": "thomashuelbert", "displayName": "Thomas Huelbert", "active": true, "timeZone": "America/Los_Angeles" }, "body": "{html}

[INFO] Titanium SDK version: 1.6.0 (01/10/11\n08:25 3452f06), G1 (1.6) droid 1 (2.2.1) sim 2.1. lag on third tab\nappearing due to network issues.

{html}", "updateAuthor": { "name": "thomashuelbert", "key": "thomashuelbert", "displayName": "Thomas Huelbert", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2011-04-15T03:19:46.000+0000", "updated": "2011-04-15T03:19:46.000+0000" } ], "maxResults": 14, "total": 14, "startAt": 0 } } }