NB: The usual blog disclaimer for this site applies to posts around HoloLens. I am not on the HoloLens team. I have no details on HoloLens other than what is on the public web and so what I post here is just from my own experience experimenting with pieces that are publicly available and you should always check out the official developer site for the product documentation.
Back in this earlier post;
Baby Steps on my HoloLens Developer Journey
I said that one of the areas that I was curious to return to on the HoloLens (device or emulator) was the topic that this page in the documentation talks about;
because I think there are some new things in running apps on the HoloLens that regular 2D UWP app developers (including me!) would want to dig into.
The ‘app’ that I put together in this recent post;
Windows 10 1607, UWP, Single Process Execution and Lifecycle Changes
is a useful tool to use here (I’m sure there are others!) as I think it can be used to show how apps running on HoloLens have the same lifecycle as all UWP apps but the path through that lifecycle varies slightly.
The official docs explain it all but I really needed to see it for myself to understand it better and this post is just a write-up of my experiments (i.e. it could be wrong, I do my best but I’m rarely 100% accurate ) in case they help others to reason over the same thing.
Starting on the PC
If I take the app that I wrote in that post and I run it on my PC after a clean installation then what happens is this.
- I launch the app from its tile on the start menu.
- The app runs up.
- I see the results below
This is what I’d expect – the app has launched from its primary tile (the tile id will be “App”) and it runs straight away and it goes through the ‘leaving background’ stage and it wasn’t already running and so the app records that these 3 things have happened.
With the app already running if I then run the app again from the start screen then it updates;
No great surprises there either – the app has now been launched twice from its primary tile and in one case it wasn’t already running and in the other it was.
The app has a button in it which pins a secondary tile so if I pin that tile (sorry about the UI here, I was being lazy on that tile icon);
then that gets pinned to the start screen and (with the app still running) I can then click on that secondary tile (it has a hard-coded ID of “App2”) and launch the app again;
and hopefully the output makes sense – the app has been launched from a secondary tile that it recognises and it was already running and so that it what I’d expect.
Beyond that, the app goes through its lifecycle that I’m used to – it goes into/out-of the background state, it suspends/resumes and sometimes it terminates.
I’ve also been running this app on the HoloLens (device/emulator)…
Switching to the HoloLens
As the documentation clearly states;
Every app starts by placing an app tile (just a Windows secondary tile https://msdn.microsoft.com/en-us/library/windows/apps/windows.ui.startscreen.secondarytile.aspx) in the HoloLens shell.
These app tiles, on placement, will start running the app. These app tiles persist and stay at the location where they are placed, acting like launchers for anytime you want to get back to the app.
Now, this took me a little while to get my head around. If I deploy my app into the HoloLens device/emulator then I see its tile on the start menu;
and then if I air-tap on it I see;
At this point, my isn’t running at all – this is the placement part of the process and when I air-tap to place the app I see this output from my little app;
This is interesting to me. It’s exactly as the documentation says – the app has not been launched from a primary tile or a secondary tile that the app knows about.
It has instead been launched by a secondary tile that the system has created (from debugging, it seems to give them a GUID based identifier). The system is going to create these for each ‘placement’ of the app that the user requests and the system is going to remember them.
If you’ve not used HoloLens beyond the emulator then this might seem a bit surprising but keep in mind that I might do something like;
- Enter room 1.
- Run my app, place it in room 1.
- Leave room 1.
- Enter room 2.
- Run my app. I’d be disappointed if the device said “it’s already running, you need to go to room 1” and especially given that room 1 might be in another building in another location so the system doesn’t do that, it lets me run my app and place it in room 2.
- Leave room 2.
- Enter room 1 where my app is still placed in that environment and ready for me to use one again, kind of like magic.
It’s worth flagging that at point 5 these rooms might well be in different locations – I left a hologram puppy in my kitchen the other day. I have every confidence that it is still there
So the system is creating these GUIDs that represent where my app has been placed and it’s remembering them for me. My app could presumably count them up by asking the system to find all of its secondary tiles but I don’t have that code in my app just yet.
The code I do have, ‘remembers’ every unique tile ID that it has been launched with which aren’t already known to it (it knows two – “App” and “App2”) under the count labelled “Number of Unknown Secondary Tiles Seen” and this is a value of 1 on the UI in the screenshot above because the app has been launched from a tile created by the system.
If I then return to the start menu and launch the app again;
Then, again, as per the docs, the app is placed again. Note that it’s on the right here;
As per the docs;
“As soon as you place and launch an app, any other active app will suspend, leaving a screenshot of its last state on its app tile wherever you placed it”
and this can be seen in the ‘window’ on the left which has gone to sleep and been replaced by a bitmap although it’s worth saying that this is from the same app rather than another app and it’s also worth saying that the app has not suspended here as the window on the right indicates but it has had its output replaced by a now slightly out of date bitmap.
I’m now in a situation which I don’t think I could get into on another Windows 10 device in exactly the same way which is that the same app has ‘launched’ into two windows on the screen coming from the same process.
Note – it’s perfectly possible for a UWP app on another Windows 10 device (e.g. PC) to open up multiple windows and then to display different UI in them but it doesn’t happen in quite the same way as here – i.e. the system doing multiple launches with unique secondary tile IDs.
I’ve written a little about multiple windows in the past.
If I run another couple of (different) apps (Edge and Feedback Hub, not entirely visible on the screenshot here but just offscreen);
then at some point both of the windows of my app go to sleep (i.e. snooze cursor in the middle of the screenshot above) and if I then go back and air-tap on the most recently used window of my app (i.e. the right hand one) then I see;
So…the app has gone into the background, been suspended, been resumed and has come back from the background. This makes sense and it lines up perfectly with this scenario from the docs;
If I then move away from my app once again and tap around on the other apps in order then at some point my app goes back to sleep.
If then air-tap on the window of my own app which was least recently used (i.e. the left one) then I see it update to show;
so the app has entered the background again, been suspended, been resumed and then it has also been launched again from from a secondary tile that the system owns.
However…it’s clear from the ‘Number of Unknown Secondary Tiles’ count not increasing that while the app didn’t create this tile ID, it has seen it before and that’s as per this scenario in the table below;
So, I think I’m starting to “get it” but I’d like to think on it a little more from the point of view of ‘state management’.
From my experiments so far (in the debugger) it would seem that each of the ‘placed’ app instances ends up with the same instance of a Window and so a developer who’d used something like the default ‘blank UWP app’ templates in Visual Studio would be on familiar ground in that when there were N ‘placements’ of their app in the mixed reality world there would only be 1 Window, 1 Frame and 1 ‘MainPage’ to worry about (and one navigation stack) although I’d like to dig in a little more to figure out what that really looks like.
This post is getting long though so I’ll come back to that one in another post and, remember, these are just experiments so inaccuracies are possible and definitely owned by me