tidev / titanium-sdk

🚀 Native iOS and Android Apps with JavaScript
https://titaniumsdk.com/
Other
2.76k stars 1.21k forks source link

Android: $ is null after switching night/day mode (SDK 10.1.0) #12559

Closed m1ga closed 3 years ago

m1ga commented 3 years ago

Describe the bug

Testing the master 10.1.0 at the moment. When switch day/night mode in a child window I get the following error:

[ERROR] TiExceptionHandler: (main) [11155,11997] /alloy/controllers/placeDetail.js:739
[ERROR] TiExceptionHandler: $.hallenDetails.fetch({
[ERROR] TiExceptionHandler:   ^
[ERROR] TiExceptionHandler: TypeError: Cannot read property 'hallenDetails' of null
[ERROR] TiExceptionHandler:     at Window.onOpen (/alloy/controllers/placeDetail.js:739:3)
[ERROR] TiExceptionHandler:     at Window.value (ti:/kroll.js:1609:27)
[ERROR] TiExceptionHandler:     at Window.value (ti:/kroll.js:1666:27)
[ERROR] TiExceptionHandler:
[ERROR] TiExceptionHandler:     org.appcelerator.kroll.runtime.v8.V8Object.nativeFireEvent(Native Method)
[ERROR] TiExceptionHandler:     org.appcelerator.kroll.runtime.v8.V8Object.fireEvent(V8Object.java:63)
[ERROR] TiExceptionHandler:     org.appcelerator.kroll.KrollProxy.doFireEvent(KrollProxy.java:994)
[ERROR] TiExceptionHandler:     org.appcelerator.kroll.KrollProxy.handleMessage(KrollProxy.java:1223)
[ERROR] TiExceptionHandler:     org.appcelerator.titanium.proxy.TiViewProxy.handleMessage(TiViewProxy.java:261)
[ERROR] TiExceptionHandler:     ti.modules.titanium.ui.WindowProxy.handleMessage(WindowProxy.java:481)
[ERROR] TiExceptionHandler:     android.os.Handler.dispatchMessage(Handler.java:102)
[ERROR] TiExceptionHandler:     android.os.Looper.loop(Looper.java:223)
[ERROR] TiExceptionHandler:     android.app.ActivityThread.main(ActivityThread.java:7660)
[ERROR] TiExceptionHandler:     java.lang.reflect.Method.invoke(Native Method)
[ERROR] V8Exception: Exception occurred at /alloy/controllers/placeDetail.js:739: Uncaught TypeError: Cannot read property 'hallenDetails' of null

code:

function onOpen(e) {
    $.hallenDetails.fetch({
        id: args.id,
        success: onFetchSuccess,
        error: function(e) {}
    });
}

and the relevant alloy parts

<Model src="hallen" id="hallenDetails" instance="true"/>
    <Window titleid="climbinghall" onClose="onClose" onOpen="onOpen">
...

It works fine when I open the window. Just switching the system to night mode will produce that error.

To Reproduce

  1. open app
  2. open child window with model and code inside onOpen
  3. change systems day/night mode
  4. error will appear

Expected behavior

Window should switch to day/night colors and execute the onOpen commands again.

Environment

Titanium SDK version: 10.1.0 master (21/03/12) CLI version: 5.3.0

Video of the error

drauggres commented 3 years ago

@m1ga I'm pretty sure that you have $ = null; in your onClose.

m1ga commented 3 years ago

nooooo....but I'll close this ticket here :roll_eyes: Might not be an issue in the SDK itself :smile:

@drauggres Can you read my code :rofl: of course you are right. there is a $ = null in the code! After removing that it works fine :+1:

drauggres commented 3 years ago

System can close your window (actually Activity) in some cases like theme, locale or orientation change. So you shouldn't dereference $ in close event handler. But leaving $ can cause memory leak (last time I worked on memory leaks this was the main reason). In my apps I dereference $ only when I'm sure that controller must me disposed, e.g. in close handler after user pressed back/close button.

P.S. I had the same problem with Android 7, when split screen feature appeared. Had to rewrite all open/close handlers in every controller.

jquick-axway commented 3 years ago

Thanks for helping out @drauggres .

When the theme changes (ie: uiMode), the activity will be destroyed and recreated with the new themed context. In Titanium, what will happen is the window will close and re-open itself (you'll receive "close" and "open" events). This is the only native android:configChange we allow to recreate the activity. All other config changes are overridden.

Also note that an activity can be destroyed/recreated like this if system Developer Option "Don't keep activities" is enabled. In this mode, only the currently displayed activity exists in memory. All of the parent activities will be temporarily destroyed and be recreated by the system when navigating back. Meaning that a parent Titanium window will be closed when displaying a child window... and when you navigate back the parent window will re-open on its own. (This situation might happen without this "Don't keep activities" if the device is struggling for memory too.)

For hyperloop, we're now recommending devs to add their native views via the Window.activity.onCreate callback as shown in the below PR. https://github.com/appcelerator/hyperloop-examples/pull/88