currently I'm experimenting with the native SDK. I have a wtc file that contains 1000 markers, the wtc's file size is about 20 MB, included in the app's assets. The app's Wikitude code roughly coresponds to your example's InternalRenderingActivity (in fact, the problem I'm going to outline can be reproduced with that example too if I put my wtc / key there).
The problem is that the tracker-loading via create2dClientTracker takes too long and that the app's UI becomes unresponsive. When switching to the respective activity it takes
- about 5 seconds until the app visibly reacts after intent issueing and shows a black Wikitude view. - another 7 seconds later I finally get something visible and working. (measured on LG Magna) - the app is completely unresponsive during that perioid, it doesn't even react on back button etc. during
Interesting detail: if the app's Wikitude-activty is shown for the first time during the app's live it will still be about 12 seconds until the detection is working, but you get to see the camera view immediately, no black view and no unresponsive UI, the app's activity switch is not delayed.
The question is: (how) can I get rid of this behaviour? The WikitudeSDK seems to strongly dependend on the activity's life-cycle methods, which means that it's usually going to be destroyed when I (temporarily) switch to another activity (e.g. especially sth. like back to a menu), destruction including its trackers. It looks as if I cannot pre-create and store the tracker-object "outside" the activity to avoid constant reloading on activity switch because its creation depends on a valid WikitudeSKD object. Or can I safely "cache" that one?
I was able to workaround the "5 seconds black / unresponsive" part of the issue by copying the large WTC into the cache-dir. However, while at first glance it seemed to somewhat help a bit, it actually revealed other problems:
- onTrackerFinishLoading is called immediately after issueing create2dClientTracker, although apparently internally nothing is "finished" at all because it will take the abovementioned about 12 seconds or so until the tracking actually works.
- when hitting the back-button while the not-really-finished-loading/initializing it not truely finished, you are sent back to the previos activity immediately. So far so good. An improvement over the original unresponsive-issue. But unfortunately that issue has only moved: when you issue an intent to enter the activity again, right after you left it, it turns out that you get a unresponsive app again. This is because Wikitude's onDestroy likes to run for a very long period of time (up to ten seconds) if it has to cleanup an instance the had been terminated in-mid of an unfinished tracker loading/ init, so as a side-effect it will essentially freeze your app if you try to recreate that same activity while onDestroy isn't done...
All in all I'm a bit lost now. While the SDK has zero problems with detecting those 1000 markers at high speed, these issues make it very problematic for my app where it is crucial that the app stays responsive / starts or continues scanning quickly while doing proper actitity handling. Any ideas are highly appreciated.
EDIT: with some funny back-stack-mess-arounds I was finally able to get what I want, namely to prevent the AR activity from being destroyed whatever activity changes I do inside the app, so that this long tracker loading / unresponsiveness issue has no chance to come up (well, initial AR activity creation aside, of course).
However, to show at least show some spinning wheel or other loading indicator for that initial load, the abovementioned sub-issue I noticed in between is still a problem, namely: onTrackerFinishLoading is called immediately after issueing create2dClientTracker, not when loading/init is actually done. This is really a show stopper because people see the cam-view, expect that it's already working, but it does not for some ten more seconds or so. And unfortunately I didn't find any class property or whatever to check a tracker's loading state beyond the not-reliable onTrackerFinishLoading. What to do?
Thanks & cheers, Daniel
over 2 years ago
Thx for the very detailed description. Now I owe you an also very detailed explanation although it's easy to explain ;)
onTrackerFinishedLoading is called as soon as the .wtc file is open. This happens very fast for you because the .wtc is bundled within the application. The callback is more helpful if the SDK has to download the .wtc from a server.
What takes then so much time is the information extraction from that .wtc file. This is not considered for the finished loading callback and there is no callback for that event at the moment. Extracting the information is usually done in a background thread. In case you create a SDK instance and immediately afterwards destroy it, the .wtc has to finish loading. This explains the unresponsiveness that you described for that use case.
Where I don't have an explanation for right now is the startup behaviour you described. As the .wtc loading is done completely asynchronously, it should not affect camera rendering. I will have a look at this.
Right now there is no way of preloading a tracker object with a .wtc file. Your only way is to keep the activity around.
But there is some light ;)
We started work for our SDK 6 which will bring massive improvements to all you mentioned. New callbacks, improved background loading and cancelation. Maybe even preloading (We're not sure about this right now). Currently we're planning to release our next major update before Christmas.
In the meantime you can try the following:
* Split up the large .wtc into multiple smaller ones and load them when needed (~150 targets per .wtc gives you some good performance)
* If you can't split them, maybe cloud recognition fits your use case better. It's nearly as quick in terms of recognition as client tracking and you're not limited to 1000 targets. 1000 targets really is the limit for client tracking and acquires a lot of work to be done on the phone.
I hope this helps you understand better what's happening in the background
over 2 years ago
thanks for you answer (although it doesn't make me too happy).
I'm really wondering why "onTrackerFinishedLoading" hasn't been implemented so it does what its name tells us. You describe the semantics of a method "onTrackerStartLoading". And indeed, the iOS native SDK's equivalent "didFinishedLoadingTargetCollectionFromURL" works as expected, it is called when the tracker loading is finished. A fix / update before christmas is nice, but unfortunately that's most likely too late for me - unless "before xmas" means "in two weeks" from now ;-)
For now I'll have no choice on Android but to stick with my idea to activate a large spinning wheel on init that runs for about 15 seconds or until a marker has been detected, whatever happens first. Ugly but I don't see any other option.
Splitting up the WTC into smaller pieces is no option neither, at least in my situation, because those 1000 markers all have the same probability of being the next potential target. Therefore I gain nothing by splitting, it only complicates things further :(
over 2 years ago
Hi Daniel, I had a look at the Android and iOS behaviour and added a little tweak so that Android now behaves the same. This change goes live with our last SDK 5.x maintenance update which we release end of August.
Hope this makes you a little hapier again ;)
over 2 years ago
thanks a lot! And end of August will even fit my schedule! Yes, that makes me *very* happy :-)