{ "id": "120982", "key": "TIMOB-15443", "fields": { "issuetype": { "id": "2", "description": "A new feature of the product, which has yet to be developed.", "name": "New Feature", "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": "16593", "description": "Release 4.0.0", "name": "Release 4.0.0", "archived": false, "released": true, "releaseDate": "2015-05-21" } ], "resolution": { "id": "1", "description": "A fix for this issue is checked into the tree and tested.", "name": "Fixed" }, "resolutiondate": "2014-10-27T17:51:48.000+0000", "created": "2013-10-09T06:26:56.000+0000", "priority": { "name": "High", "id": "2" }, "labels": [ "android", "module", "module_api", "notable" ], "versions": [], "issuelinks": [ { "id": "46190", "type": { "id": "10003", "name": "Relates", "inward": "relates to", "outward": "relates to" }, "outwardIssue": { "id": "145065", "key": "TIDOC-2141", "fields": { "summary": "Android Module: Update guide for new lifecycle access", "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" } }, "priority": { "name": "Medium", "id": "3" }, "issuetype": { "id": "2", "description": "A new feature of the product, which has yet to be developed.", "name": "New Feature", "subtask": false } } } }, { "id": "32430", "type": { "id": "10003", "name": "Relates", "inward": "relates to", "outward": "relates to" }, "inwardIssue": { "id": "103072", "key": "TIMOB-11360", "fields": { "summary": "Tooling: Android module build scripts throw NoClassFoundException when native Android project is included as library which has UI built in XML", "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" } }, "priority": { "name": "High", "id": "2" }, "issuetype": { "id": "1", "description": "A problem which impairs or prevents the functions of the product.", "name": "Bug", "subtask": false } } } }, { "id": "43939", "type": { "id": "10003", "name": "Relates", "inward": "relates to", "outward": "relates to" }, "inwardIssue": { "id": "134189", "key": "TIMOB-17747", "fields": { "summary": "Android: Native module onStart() lifecycle method never called for Alloy project", "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" } }, "priority": { "name": "High", "id": "2" }, "issuetype": { "id": "1", "description": "A problem which impairs or prevents the functions of the product.", "name": "Bug", "subtask": false } } } } ], "assignee": { "name": "jalter", "key": "jalter", "displayName": "Jon Alter", "active": true, "timeZone": "America/Los_Angeles" }, "updated": "2015-03-30T21:21:07.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": "The current Android module API offers access to the *application* lifecycle, but this is mostly irrelevant for Android (it's the iOS model!), where code needs access to the *Activity* lifecycle (i.e. onCreate, onResume, onPause, onStop, onDestroy, onActivityResult).\r\n\r\nA good example is this class in the Facebook SDK: https://developers.facebook.com/docs/reference/android/current/UiLifecycleHelper\r\n\r\nCurrently, this class cannot be used in module code that runs in the context of a Window or TabGroup, since the module does not have access to that Activity's lifecycle events. This greatly complicates module porting to Titanium, since using such classes requires creating non-UI activities, and then we need methods to sync between the various Activities.\r\n\r\nh3. Proposal\r\n# Add a new dictionary parameter to Ti.UI.createWindow and createTabGroup, attachAndroidModule: 'modulename'\r\n# If attachAndroidModule is specified, the module is loaded prior to Activity creation and its lifecycle events correspond to those of the created UI Activity.\r\n# The Javascript does not change - the module is \"required\" and used as before.\r\n# Clearly the module can be attached to multiple Activities in a Titanium app - just as an Android library can be used by multiple Activities in in a native Android app, and in each case the events correspond to the Activity in use.\r\n# I would deprecate the current lifecycle events in the Android module, since they're confusing in the Android context. However, if desired, I suppose it's possible to maintain \"legacy\" module behavior (per module) through tiapp.xml configuration parameters.\r\n\r\nThis is yet another stumbling block to easy porting of 3rd party code. The Titanium community would greatly benefit from this improvement.", "attachment": [], "flagged": false, "summary": "Android: Allow full Activity lifecycle access for Titanium modules", "creator": { "name": "mokesmokes", "key": "mokesmokes", "displayName": "Mark Mokryn", "active": true, "timeZone": "Asia/Jerusalem" }, "subtasks": [], "reporter": { "name": "mokesmokes", "key": "mokesmokes", "displayName": "Mark Mokryn", "active": true, "timeZone": "Asia/Jerusalem" }, "environment": "Android SDK 3.1.3.GA, 3.2.0", "closedSprints": [ { "id": 241, "state": "closed", "name": "2014 Sprint 22 SDK", "startDate": "2014-10-27T22:25:43.407Z", "endDate": "2014-11-08T01:00:00.000Z", "completeDate": "2014-11-10T20:10:00.899Z", "originBoardId": 114 }, { "id": 230, "state": "closed", "name": "2014 Sprint 21 SDK", "startDate": "2014-10-13T22:00:57.270Z", "endDate": "2014-10-25T00:00:00.000Z", "completeDate": "2014-10-27T16:33:06.432Z", "originBoardId": 114 } ], "comment": { "comments": [ { "id": "302726", "author": { "name": "ingo", "key": "ingo", "displayName": "Ingo Muschenetz", "active": true, "timeZone": "America/Los_Angeles" }, "body": "We were able to address the issues faced in TIMOB-11360 for 3.3.0, but are unable to tackle this problem this release as it required too much engineering work. We will tackle this in a subsequent release.", "updateAuthor": { "name": "ingo", "key": "ingo", "displayName": "Ingo Muschenetz", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2014-04-28T16:35:14.000+0000", "updated": "2014-04-28T16:35:14.000+0000" }, { "id": "325113", "author": { "name": "mokesmokes", "key": "mokesmokes", "displayName": "Mark Mokryn", "active": true, "timeZone": "Asia/Jerusalem" }, "body": "A general question: this is targeted for 3.5.0. What is the current status?\r\nTo make it simpler: what would be good is if the proxies can access the relevant activity.\r\nFor example: \r\n{code}\r\nvar someProxyObject = createProxyObject({activity: window.activity}); // or tabGroup.activity in the proxy creation dictionary\r\n{code}\r\nThen inside the proxy module we should be able to do a setActivity(activity) (setActivity is already part of the KrollProxy API).\r\nAnd then add the proxy object to the activity lifecycle listeners.\r\nSo really all we need is a method like ActivityProxy.getActivity(), with the tricky aspect being that the activity proxy exists before the activity is created.... As a general note, I'm not clear as to the utility of initActivity (in KrollProxy currently) since in the normal case it sets the activity to be the current activity, which would be correct only if the proxy was created while the window/tab group is in the Resumed state.\r\nNote that it is possible to hack around this by calling a proprietary method on the proxy, e.g. proxy.onResume when the window/tabgroup activity is resumed - in this case we know that TiApplication.getInstance().getCurrentActivity() provides the right activity, and we can handle what we wish. However, it is a drag to expect app developers to handle this in all their windows/tabgroups when using some modules.\r\nBottom line - there should be a clear cut way for proxies to be associated to activities and participate in the activity lifecycle. It should be supported in the code and clearly documented in the Android module development guide. This approach makes more sense than what I wrote in the original issue, and also should be easier to implement.\r\n", "updateAuthor": { "name": "mokesmokes", "key": "mokesmokes", "displayName": "Mark Mokryn", "active": true, "timeZone": "Asia/Jerusalem" }, "created": "2014-09-23T09:23:45.000+0000", "updated": "2014-09-23T09:32:10.000+0000" }, { "id": "325378", "author": { "name": "mokesmokes", "key": "mokesmokes", "displayName": "Mark Mokryn", "active": true, "timeZone": "Asia/Jerusalem" }, "body": "Note that the workaround I mentioned above (calling a proxy method during window.activity.onResume so that getCurrentActivity is correct) requires that this PR is accepted - onResume must be called synchronously.\r\nhttps://github.com/appcelerator/titanium_mobile/pull/6160", "updateAuthor": { "name": "mokesmokes", "key": "mokesmokes", "displayName": "Mark Mokryn", "active": true, "timeZone": "Asia/Jerusalem" }, "created": "2014-09-24T06:29:02.000+0000", "updated": "2014-09-24T06:29:02.000+0000" }, { "id": "325430", "author": { "name": "mokesmokes", "key": "mokesmokes", "displayName": "Mark Mokryn", "active": true, "timeZone": "Asia/Jerusalem" }, "body": "An example module which needs the PR noted above, and which will be further simplified if this ticket is resolved as I noted: https://github.com/mokesmokes/titanium-android-facebook", "updateAuthor": { "name": "mokesmokes", "key": "mokesmokes", "displayName": "Mark Mokryn", "active": true, "timeZone": "Asia/Jerusalem" }, "created": "2014-09-24T15:41:06.000+0000", "updated": "2014-09-24T15:41:06.000+0000" }, { "id": "326025", "author": { "name": "mokesmokes", "key": "mokesmokes", "displayName": "Mark Mokryn", "active": true, "timeZone": "Asia/Jerusalem" }, "body": "PR: https://github.com/appcelerator/titanium_mobile/pull/6179\r\nHow to test:\r\nIn Studio create an Android module with the standard template. Replace the file ExampleProxy.java with the following (change the package name if required):\r\n{code}\r\npackage com.lifecycle;\r\n\r\nimport org.appcelerator.kroll.KrollDict;\r\nimport org.appcelerator.kroll.KrollProxy;\r\nimport org.appcelerator.kroll.annotations.Kroll;\r\nimport org.appcelerator.titanium.TiC;\r\nimport org.appcelerator.titanium.util.Log;\r\nimport org.appcelerator.titanium.util.TiConfig;\r\nimport org.appcelerator.titanium.util.TiConvert;\r\n\r\nimport android.app.Activity;\r\nimport android.os.Bundle;\r\n\r\n@Kroll.proxy(creatableInModule=LifecycleModule.class)\r\npublic class ExampleProxy extends KrollProxy\r\n{\r\n\t// Standard Debugging variables\r\n\tprivate static final String LCAT = \"ExampleProxy\";\r\n\tprivate static final boolean DBG = TiConfig.LOGD;\r\n\tprivate String name;\r\n\r\n\t// Constructor\r\n\tpublic ExampleProxy()\r\n\t{\r\n\t\tsuper();\r\n\t}\r\n\r\n\t// Handle creation options\r\n\t@Override\r\n\tpublic void handleCreationDict(KrollDict options)\r\n\t{\r\n\t\tsuper.handleCreationDict(options);\r\n\r\n\t\tif (options.containsKey(\"name\")) {\r\n\t\t\tname = TiConvert.toString(options, \"name\");\r\n\t\t\tLog.d(LCAT, \"example created with name: \" + name);\r\n\t\t}\r\n\t}\r\n\r\n\t@Override\r\n\tprotected void initActivity(Activity activity) {} // empty since we setActivity when activity is determined\r\n\r\n\t@Override\r\n\tpublic void onDestroy(Activity activity) {\r\n\t\tLog.d(LCAT, \"onDestroy called for \" + name);\t\r\n\t}\r\n\r\n\t@Override\r\n\tpublic void onPause(Activity activity) {\r\n\t\tLog.d(LCAT, \"onPause called for \" + name);\r\n\t}\r\n\r\n\t@Override\r\n\tpublic void onResume(Activity activity) {\r\n\t\tLog.d(LCAT, \"onResume called for \" + name);\r\n\t}\r\n\r\n\t@Override\r\n\tpublic void onStart(Activity activity) {\r\n\t\tLog.d(LCAT, \"onStart called for \" + name);\t\r\n\t}\r\n\r\n\t@Override\r\n\tpublic void onStop(Activity activity) {\r\n\t\tLog.d(LCAT, \"onStop called for \" + name);\r\n\t}\r\n\r\n\t@Override\r\n\tpublic void onCreate(Activity activity, Bundle savedInstanceState){\r\n\t\tLog.d(LCAT, \"onCreate called for \" + name);\r\n\t}\r\n}\r\n{code}\r\n\r\nThen try the module with the following test app. Watch the console for output during the activity lifecycle. Note that the proxy can be created before or after the Window or TabGroup is opened - the test app tests both cases for both Windows and TabGroups. Also tested with and without \"Do not keep activities\"\r\n{code}\r\nTitanium.UI.setBackgroundColor('#000');\r\nvar lifecycle = require('com.lifecycle');\r\n\r\nvar tabGroup = Titanium.UI.createTabGroup();\r\nvar tabProxyPreOpen = lifecycle.createExample({name: 'tabProxyPreOpen', lifecycleContainer: tabGroup});\r\n\r\nvar win1 = Titanium.UI.createWindow({ \r\n title:'Tab 1',\r\n backgroundColor:'#fff'\r\n});\r\nvar tab1 = Titanium.UI.createTab({ \r\n icon:'KS_nav_views.png',\r\n title:'Tab 1',\r\n window:win1\r\n});\r\n\r\nvar btn = Titanium.UI.createButton({\r\n\ttitle: 'open a new window',\r\n\twidth:'200dp',\r\n\theight: '50dp'\r\n});\r\nwin1.add(btn);\r\nvar childWin = Ti.UI.createWindow();\r\nchildWin.addEventListener('open', function(e){\r\n Ti.API.info(\"proxies created after the open event may (of course) miss the onCreate event\");\r\n\tvar winProxyPostOpen = lifecycle.createExample({name: 'winProxyPostOpen', lifecycleContainer: childWin});\r\n});\r\n\r\nvar winProxyPreOpen = lifecycle.createExample({name: 'winProxyPreOpen', lifecycleContainer: childWin});\r\nbtn.addEventListener('click', function(e){\r\n\tchildWin.open();\r\n});\r\n\r\nvar win2 = Titanium.UI.createWindow({ \r\n title:'Tab 2',\r\n backgroundColor:'#fff'\r\n});\r\nvar tab2 = Titanium.UI.createTab({ \r\n icon:'KS_nav_ui.png',\r\n title:'Tab 2',\r\n window:win2\r\n});\r\n\r\ntabGroup.addTab(tab1); \r\ntabGroup.addTab(tab2); \r\n\r\ntabGroup.addEventListener('open', function(e){\r\n\tvar tabProxyPostOpen = lifecycle.createExample({name: 'tabProxyPostOpen', lifecycleContainer: tabGroup});\r\n});\r\n\r\ntabGroup.open();\r\n{code}", "updateAuthor": { "name": "mokesmokes", "key": "mokesmokes", "displayName": "Mark Mokryn", "active": true, "timeZone": "Asia/Jerusalem" }, "created": "2014-09-28T23:49:54.000+0000", "updated": "2014-09-30T08:46:36.000+0000" }, { "id": "326026", "author": { "name": "mokesmokes", "key": "mokesmokes", "displayName": "Mark Mokryn", "active": true, "timeZone": "Asia/Jerusalem" }, "body": "Note: this is not a breaking change. All existing proxies should work just fine.", "updateAuthor": { "name": "mokesmokes", "key": "mokesmokes", "displayName": "Mark Mokryn", "active": true, "timeZone": "Asia/Jerusalem" }, "created": "2014-09-28T23:50:50.000+0000", "updated": "2014-09-28T23:50:50.000+0000" }, { "id": "326035", "author": { "name": "fokkezb", "key": "fokke", "displayName": "Fokke Zandbergen", "active": true, "timeZone": "Europe/Amsterdam" }, "body": "I hope this PR can be merged in 3.4.1 - or are you using semver nowadays [~ingo]?", "updateAuthor": { "name": "fokkezb", "key": "fokke", "displayName": "Fokke Zandbergen", "active": true, "timeZone": "Europe/Amsterdam" }, "created": "2014-09-29T05:07:22.000+0000", "updated": "2014-09-29T05:07:22.000+0000" }, { "id": "326311", "author": { "name": "mokesmokes", "key": "mokesmokes", "displayName": "Mark Mokryn", "active": true, "timeZone": "Asia/Jerusalem" }, "body": "I updated the PR to add onCreate to TiLifecycle. Also updated the example above to account for this. This will break code that does not inherit from KrollProxy and uses TiLifecycle. In practice, there were only 5 files in titanium_mobile that needed the trivial fix of importing android.os.Bundle and adding an empty onCreate function. However, there may be external modules that use TiLifecycle and don't inherit from KrollProxy. Thus it's important to merge this ASAP so that developers get a heads up on the small change required. \r\n\r\nAlso note that the new PR for swipeable tabs https://github.com/appcelerator/titanium_mobile/pull/6008 adds support for onSaveInstanceState and onRestoreInstanceState. So these two PRs give Titanium (and external modules) a lot more flexibility, and enable porting of 3rd party Android libraries much easier.", "updateAuthor": { "name": "mokesmokes", "key": "mokesmokes", "displayName": "Mark Mokryn", "active": true, "timeZone": "Asia/Jerusalem" }, "created": "2014-09-30T08:51:50.000+0000", "updated": "2014-09-30T08:51:50.000+0000" }, { "id": "326313", "author": { "name": "mokesmokes", "key": "mokesmokes", "displayName": "Mark Mokryn", "active": true, "timeZone": "Asia/Jerusalem" }, "body": "[~ingo] also noting that the assignee for this ticket is inactive...", "updateAuthor": { "name": "mokesmokes", "key": "mokesmokes", "displayName": "Mark Mokryn", "active": true, "timeZone": "Asia/Jerusalem" }, "created": "2014-09-30T09:05:36.000+0000", "updated": "2014-09-30T09:05:36.000+0000" }, { "id": "326331", "author": { "name": "ingo", "key": "ingo", "displayName": "Ingo Muschenetz", "active": true, "timeZone": "America/Los_Angeles" }, "body": "[~mokesmokes] thank you. We haven't yet started Sprint 21, so that would be switched before we started. I would like to have taken this up in Sprint 20, but we need to address an issue with Google play services that came up urgently that we have to address first (TIMOB-17798)", "updateAuthor": { "name": "ingo", "key": "ingo", "displayName": "Ingo Muschenetz", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2014-09-30T14:04:00.000+0000", "updated": "2014-09-30T14:04:00.000+0000" }, { "id": "326341", "author": { "name": "mokesmokes", "key": "mokesmokes", "displayName": "Mark Mokryn", "active": true, "timeZone": "Asia/Jerusalem" }, "body": "[~ingo] I have no idea what the \"sprints\" are, and I get the urgency with Google Play Services causing crashes suddenly.... so yes, that requires top priority but this particular PR is very urgent too since we need this functionality to develop a new Facebook module - and that's critical too since Facebook changed a ton of stuff and their old APIs are being killed very soon. Actually it may be even worse: Facebook now requires approval for new apps seeking extended permissions, and I'm not sure if an app built with the old module will pass their review. It will be very hard, perhaps impossible to develop a solid FB module without this. Plus there is a minor breaking change here (onCreate in TiLifecycle) so best to do it as early as possible so people fix external modules before GA (that should be rare - only 5 files in titanium_mobile needed a fix) if required. 3.5.0 really must have this included.", "updateAuthor": { "name": "mokesmokes", "key": "mokesmokes", "displayName": "Mark Mokryn", "active": true, "timeZone": "Asia/Jerusalem" }, "created": "2014-09-30T15:27:06.000+0000", "updated": "2014-09-30T15:28:46.000+0000" }, { "id": "328018", "author": { "name": "mokesmokes", "key": "mokesmokes", "displayName": "Mark Mokryn", "active": true, "timeZone": "Asia/Jerusalem" }, "body": "A note regarding the PR: https://github.com/appcelerator/titanium_mobile/pull/6179\r\nI made a design decision to reduce proxy boilerplate code to a minimum. The only thing proxies (Java obviously) need to do is implement the lifecycle methods (onCreate, onResume etc if they want to get these events) - zero boilerplate. On the Javascript side the only thing required is for the developer to pass lifecycleContainer (see the example) in the proxy creation dictionary.\r\nThe downside of this approach is that if a Javascript developer passes the lifecycleContainer property to a proxy that doesn't require it, TiBaseActivity will process these events for proxies that don't need it. This has no harmful effects other than overhead, and will only occur if the Javascript developer doesn't understand what he's doing....\r\nTwo options:\r\n1. Keep as I designed it, no proxy boilerplate code, and document that lifecycleContainer should be used (in Javascript) only for proxies that require it. (obviously this is my preference)\r\n2. Or I can remove the changes in KrollProxy.java and proxy developers will need to add that code into each proxy they write which needs the Activity lifecycle.\r\n\r\n[~ingo] please ask your team to provide input on this design decision, I can easily modify it if required. Thanks.\r\n", "updateAuthor": { "name": "mokesmokes", "key": "mokesmokes", "displayName": "Mark Mokryn", "active": true, "timeZone": "Asia/Jerusalem" }, "created": "2014-10-14T13:37:45.000+0000", "updated": "2014-10-14T13:37:45.000+0000" }, { "id": "329155", "author": { "name": "mokesmokes", "key": "mokesmokes", "displayName": "Mark Mokryn", "active": true, "timeZone": "Asia/Jerusalem" }, "body": "Added onCreateOptionsMenu, onPrepareOptionsMenu to the interfaces in TiLifecycle. For example, I'm using this in a Chromecast module to add the Cast button to the ActionBar, from the proxy. Modules such as Facebook, Chromecast, etc really need this PR.", "updateAuthor": { "name": "mokesmokes", "key": "mokesmokes", "displayName": "Mark Mokryn", "active": true, "timeZone": "Asia/Jerusalem" }, "created": "2014-10-23T13:42:43.000+0000", "updated": "2014-10-23T13:42:43.000+0000" }, { "id": "329421", "author": { "name": "jalter", "key": "jalter", "displayName": "Jon Alter", "active": true, "timeZone": "America/Los_Angeles" }, "body": "PR with CR fix: https://github.com/appcelerator/titanium_mobile/pull/6272\r\n\r\nThanks again [~mokesmokes]. You rock.", "updateAuthor": { "name": "jalter", "key": "jalter", "displayName": "Jon Alter", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2014-10-24T21:21:34.000+0000", "updated": "2014-10-24T21:23:36.000+0000" }, { "id": "329430", "author": { "name": "mokesmokes", "key": "mokesmokes", "displayName": "Mark Mokryn", "active": true, "timeZone": "Asia/Jerusalem" }, "body": "[~jalter] thanks for merge! Unfortunately though it seems you forked my branch too early, and you missed the commit for onCreateOptionsMenu and onPrepareOptionsMenu. https://github.com/mokesmokes/titanium_mobile/commit/5764a42c8d8604d17a8e994309f5293997d0b551\r\nCan't do a Chromecast module without this :( TiBaseActivity and TiLifecycle affected, same exact pattern as all the other listeners, already being used in my app so known to work.", "updateAuthor": { "name": "mokesmokes", "key": "mokesmokes", "displayName": "Mark Mokryn", "active": true, "timeZone": "Asia/Jerusalem" }, "created": "2014-10-24T22:04:07.000+0000", "updated": "2014-10-24T22:04:52.000+0000" }, { "id": "329528", "author": { "name": "mokesmokes", "key": "mokesmokes", "displayName": "Mark Mokryn", "active": true, "timeZone": "Asia/Jerusalem" }, "body": "Guys please reopen this to add the last commit in my PR so we can forget this issue for good.... Thanks!", "updateAuthor": { "name": "mokesmokes", "key": "mokesmokes", "displayName": "Mark Mokryn", "active": true, "timeZone": "Asia/Jerusalem" }, "created": "2014-10-27T15:45:23.000+0000", "updated": "2014-10-27T15:45:23.000+0000" }, { "id": "329555", "author": { "name": "jalter", "key": "jalter", "displayName": "Jon Alter", "active": true, "timeZone": "America/Los_Angeles" }, "body": "PR with merge conflicts resolved: https://github.com/appcelerator/titanium_mobile/pull/6275", "updateAuthor": { "name": "jalter", "key": "jalter", "displayName": "Jon Alter", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2014-10-27T17:50:45.000+0000", "updated": "2014-10-27T17:50:45.000+0000" }, { "id": "329578", "author": { "name": "mokesmokes", "key": "mokesmokes", "displayName": "Mark Mokryn", "active": true, "timeZone": "Asia/Jerusalem" }, "body": "[~jalter] thanks for the review and the work! :)", "updateAuthor": { "name": "mokesmokes", "key": "mokesmokes", "displayName": "Mark Mokryn", "active": true, "timeZone": "Asia/Jerusalem" }, "created": "2014-10-27T20:05:30.000+0000", "updated": "2014-10-27T20:05:30.000+0000" }, { "id": "329707", "author": { "name": "mokesmokes", "key": "mokesmokes", "displayName": "Mark Mokryn", "active": true, "timeZone": "Asia/Jerusalem" }, "updateAuthor": { "name": "mokesmokes", "key": "mokesmokes", "displayName": "Mark Mokryn", "active": true, "timeZone": "Asia/Jerusalem" }, "created": "2014-10-28T06:58:44.000+0000", "updated": "2014-10-28T07:00:32.000+0000" }, { "id": "329747", "author": { "name": "ingo", "key": "ingo", "displayName": "Ingo Muschenetz", "active": true, "timeZone": "America/Los_Angeles" }, "body": "[~mokesmokes] We'll be happy to update it (cc [~bhatfield]). However, have you considered writing a blog post about your usage of it for tidev.io? I know that group of individuals is always looking for great content and this sounds like a great topic for that site.", "updateAuthor": { "name": "ingo", "key": "ingo", "displayName": "Ingo Muschenetz", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2014-10-28T14:51:44.000+0000", "updated": "2014-10-28T14:51:44.000+0000" }, { "id": "329748", "author": { "name": "fokkezb", "key": "fokke", "displayName": "Fokke Zandbergen", "active": true, "timeZone": "Europe/Amsterdam" }, "body": "Haha, you're more then welcome [~mokesmokes], though I guess you'll agree that the guides need to be updated as well. But those changes then might use some of the blog? Mail me at mail@tidev.io if you're interested.", "updateAuthor": { "name": "fokkezb", "key": "fokke", "displayName": "Fokke Zandbergen", "active": true, "timeZone": "Europe/Amsterdam" }, "created": "2014-10-28T14:56:02.000+0000", "updated": "2014-10-28T14:56:02.000+0000" }, { "id": "329751", "author": { "name": "mokesmokes", "key": "mokesmokes", "displayName": "Mark Mokryn", "active": true, "timeZone": "Asia/Jerusalem" }, "body": "I'll gladly blog about it as soon as I get my product release out ;-) Will do it soon.", "updateAuthor": { "name": "mokesmokes", "key": "mokesmokes", "displayName": "Mark Mokryn", "active": true, "timeZone": "Asia/Jerusalem" }, "created": "2014-10-28T15:30:05.000+0000", "updated": "2014-10-28T15:30:05.000+0000" }, { "id": "343849", "author": { "name": "hpham", "key": "hpham", "displayName": "Hieu Pham", "active": true, "timeZone": "America/Los_Angeles" }, "body": "3.5.X backport: https://github.com/appcelerator/titanium_mobile/pull/6650", "updateAuthor": { "name": "hpham", "key": "hpham", "displayName": "Hieu Pham", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2015-02-18T23:15:49.000+0000", "updated": "2015-02-18T23:15:49.000+0000" }, { "id": "347796", "author": { "name": "eharris", "key": "eharris", "displayName": "Ewan Harris", "active": true, "timeZone": "Europe/Dublin" }, "body": "Verified using:\r\n\r\nMac OSX 10.10.2\r\nTitanium SDK build: 4.0.0.v20150323131014\r\nTitanium CLI, build: 4.0.0-alpha\r\nAlloy: 1.6.0-alpha\r\nNexus 5 (5.0.1)\r\n\r\nCreated a module and added functions that uses the activity lifecycle. It works as expected.\r\n\r\nClosing ticket.", "updateAuthor": { "name": "eharris", "key": "eharris", "displayName": "Ewan Harris", "active": true, "timeZone": "Europe/Dublin" }, "created": "2015-03-30T21:21:02.000+0000", "updated": "2015-03-30T21:21:02.000+0000" } ], "maxResults": 25, "total": 25, "startAt": 0 } } }