Re-opening a running app resets UI made from TypeScript

nativescriptcore
android

#1

As the title suggest, I’m having issues with retaining the user interface when going back in to the application.
It contains a fair bit of UI made using TypeScript and the side effect of the UI resetting back to whatever the XML provides is not ideal, in any case for that matter.

Following is a sample code producing the same exact result

<Page xmlns="http://schemas.nativescript.org/tns.xsd" loaded="pageLoaded" class="page">
    <Page.actionBar>
        <ActionBar title="My App" icon="" class="action-bar">
        </ActionBar>
    </Page.actionBar>
    <StackLayout>
        <Label text="Button below is generated from code" />
	<StackLayout id="buttonlayout">
		<!-- Button inserts here via ts -->
	</StackLayout>
    </StackLayout>
</Page>
import { EventData } from 'data/observable';
import { StackLayout } from 'ui/layouts/stack-layout';
import { Button } from 'ui/button';

var page = null;
var firstLoad = true;

export function pageLoaded(args: EventData) {
	console.log("pageLoaded");

	if (firstLoad == true) {
		firstLoad = false;

		page = args.object;
		var buttonlayout = <StackLayout>(page.getViewById("buttonlayout"));
		buttonlayout.addChild( new Button() );
	}
}

Now, one might argue that I should not do the “if (firstLoad…)” statement to retain the button, but the obvious part there is that we’re really just making a new button every time. That approach will not work in the actual application I’m working on.

It seems to me that whenever the application is closed (not exited) and then re-opened, the logic behind stays put (hence the firstLoad statement, which works as intended), but the user interface is reloaded regardless. Seems it’s actually reloading the XML file, and any references to the UI via statements like page.getViewById(“MyFancyLayout”) that was done before the application was closed (not exited) cease to work.

Not tested on iOS.

What gives?


#2

Simply that’s how loaded event works, but that doesn’t mean your native views are recreated every time. For example, your scroll position in ScrollView is still retained when you come back. If you debug further you will notice createNativeView for each component will be called only once.


#3

Let me give you an example modified by the original example code.

This application provides a single button from XML in which you tap, will spawn new buttons on the StackLayout id “buttonlayout”.
When we now re-open the app, the created buttons disappear and the “Create new button” button cease to work (though is still visible).
It can be “fixed” by having the “page = args.object” statement outside the firstLoad check, but this proves that something odd happens, as if the UI/DOM completely reloads, and invalidates any previous references to it.

<Page xmlns="http://schemas.nativescript.org/tns.xsd" loaded="pageLoaded" class="page">
    <Page.actionBar>
        <ActionBar title="My App" icon="" class="action-bar">
        </ActionBar>
    </Page.actionBar>
    <StackLayout>
        <Button text="Create new button" onTap="onButtonTap" />
	<StackLayout id="buttonlayout">
	</StackLayout>
    </StackLayout>
</Page>
import { EventData } from 'data/observable';
import { StackLayout } from 'ui/layouts/stack-layout';
import { Button } from 'ui/button';

var page = null;
var firstLoad = true;

export function pageLoaded(args: EventData) {
	console.log("pageLoaded");

	if (firstLoad == true) {
		firstLoad = false;

		page = args.object;
	}
}

export function onButtonTap(args: EventData)  {
	var buttonlayout = <StackLayout>(page.getViewById("buttonlayout"));
	buttonlayout.addChild( new Button() );
}

You see, I’m just getting into mobile app development and have extensive background from desktop programming with C++ and Qt, though very irrelevant here, but things appear to work very differently and not so intuitive.


#4

I found out what’s up. The view isn’t actually reloading, as already sort of mentioned, but a new Page is created on top each time the app is re-opened. The Page is obviously then based off the XML file. I can get back to the original Page by hitting the Back button.
I found this using the “tns debug” command and comparing different heap snapshots. Page increases every time I re-open the application.

I’ll see what I can find out poking around this finding. If someone else knows anything, I would appreciate any sorts of pointers!


#5

Android uses Fragments for navigation, current fragment is always removed on pause and recreated on resume so I believe that’s the reason there.


#6

Seems I’m unable to resolve this so I need to move forward trying other alternatives to cross platform app development… It can be a fault from my side or a bug in NativeScript, or whatever, but I cannot invest more time in this… it’s business related so I would probably get frowned on if I spend much more time on this.
I will check in this thread regularly to see if someone provides further assistance. I really enjoyed NativeScript though…