Cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Clockface stops working with SDK 3

ANSWERED

I'm having a strange issue.  I made an update to my Clarity clockface and at the same time updated it to SDK 3.  I received a couple of emails from android users saying their version was no longer displaying properly.  For others it seems to be fine.

 

Now in doing further testing I can no longer load the clockface myself!

 

I've created two private clock faces.  One built with SDK 2 and one with SDK 3 both with identical code. 

 

SDK 2

https://gam.fitbit.com/gallery/clock/93be9a9c-25ae-4fd3-86ef-8415739b24cc

 

SDK 3

https://gam.fitbit.com/gallery/clock/23ae3f5c-fdc5-474f-b1e4-8db85eccb5b4

 

I can load the SDK 2 version fine, but the SDK 3 version fails. 

 

Both work fine with the simulator.  If I try and sideload the SDK 3 is fails with "Sideload of app failed.  Internal Error."  I can sideload the SDK 2 version fine.  Also if I first sideload the SDK 2 version and then sideload the SDK 3 version it works!  Which I think explains why I was able to upgrade by existing Clairty clockface once it was approved for public distribution (since I was already running the SDK 2 version).

 

Any help most welcome!

 

Best Answer
0 Votes
1 BEST ANSWER

Accepted Solutions

I agree. I'm currently throwing together a FAQ on SDK development. Here's a foretaste:

 

Spoiler

Don't initialise anything you don't have to immediately. For example, initialise elements for secondary screens only when they’re about to be displayed. If you structure such code into objects, you can also reduce memory use.

getElementById(), getElementsByClassName(), etc, can be quite slow. If your .gui is large but well structured, minimise calls to document.getElementById by using the element’s immediate parent, rather than ‘document’, if there are several elements beneath that parent. This will spare the startup code from having to look through the whole DOM every time.

 

This is a big job. Before getting carried away with it, it might be wise to comment out some chunks of code, variables and/or UI elements that aren't initially required, just to verify the hypothesis (and maybe narrow down focus areas).

Peter McLennan
Gondwana Software

View best answer in original post

Best Answer
0 Votes
16 REPLIES 16

I'd definitely remove gallery versions and sideloaded versions, then make sure you're still having the issue.

 

Have you checked the new migration guide for hints on changes? https://dev.fitbit.com/build/guides/migration/

Best Answer
0 Votes

I definitely still have the same problem with so sideloaded versions. 

 

I'm not 100% sure what you mean by remove gallery versions: I installed a random other clockface  before trying to load the new version (is that what you mean?) - and still had the problem.  Of you you mean remove all the private versions from the gallery? (But these all have different UUIDs I think).

 

I did look at the migration guide and saw  nothing obvious.  It's a fairly standard clock face which shows activity details etc and handles a second timezone.  I do save settings to a cbor file (tried changing to to json but no joy).

Best Answer
0 Votes

The behaviour you described sounds like what happens if a clockface doesn't start within the allowed 10 seconds. Unfortunately, SDK3 code seems to be a fair bit slower to start (but is much faster when running). Some of my apps take almost 10 seconds just to compile, so they don't get much time to initialise themselves before the OS kills them. Your clockfaces shouldn't suffer from this problem, but maybe think about whether you've got any slow startup code in there — especially blocking while waiting for comms or lengthy storage operations. (Loading a small .cbor should be fine.)

Peter McLennan
Gondwana Software
Best Answer
0 Votes

Thanks for your advice.  I'll start looking at this and see if I can figure out the timings. 

 

This is my first ever javascript programming so it is easily possible I made a rookie mistake (its a long time since I coded seriously - we're talking fortran!).  In particular I copied the messaging code without fully understanding it all! 

 

One thing I do is to send the current stored settings to the companion if/when it is alive.  This is so that and settings changed on the watch itself are made visible in the settings on the phone. I guess the companion will always run when the clockface is installed.

 

I've put the code on GitHub in case anyone has time to take a quick look.

 

https://github.com/apgr/FitBit-Clarity

 

 

 

Best Answer
0 Votes

Here is a screen cap of the SDK2 version being sideloaded into my versa...

 

Pasted Graphic.jpg

 

 

Best Answer
0 Votes

Alas, the companion comes and goes. That shouldn't matter if you've coded your comms not to make any assumptions about its availability. However, if your device code blocks (eg, loops) waiting for the companion socket to open, you're asking for trouble. Hopefully you didn't do that!

Peter McLennan
Gondwana Software
Best Answer
0 Votes

I think I'm OK on this.  The relevant code is

 

//------------- Companion is alive ---------------------------------
    messaging.peerSocket.onopen = () => {
    console.log("Companion is awake.....");
    sendValue("DST", settings.DST);
    sendValue("TZtoggle", settings.TZtoggle);
    sendValue("TimeZone", settings.TZindex);
    sendValue("secondTimeZone", settings.secondTimeZone);
    sendValue("Activity-slider", settings.Actopacity*100);
    sendValue("slider", settings.TZopacity*100);
};

 

I assume that this code segment is only executed if the open event happens (although this is the area I really am most unsure about). 

 

Best Answer
0 Votes

Yes, that looks okay.

 

I just had a quick squiz at your source code (without actually trying to run it). You do have a LOT of startup code in there. getElementbyId (etc) are very slow. In addition, tile list items actually take a while to be initialised (even before your code gets a chance to run), and you've got quite a few of those. This is strengthening my concern about slow start-up time.

 

Before embarking on any major refactoring, have you verified that you're not out of memory? Can you get app/index.js to console.log('hello') at the very start?

Peter McLennan
Gondwana Software
Best Answer
0 Votes

Thanks - I really appreciate you taking the time to help!  I added the colsole.log('hello") at the start

I then sideloaded with SDK2 and get the following...

 

sdk2sdk2

If I then immediately switch the SDK3 I get

 

Pasted Graphic 1.jpg

 

If I first delete the sideloded app and try to sideload under SDK3 I get

 

Pasted Graphic 2.jpg

where the only new line of output is the red one.

Best Answer
0 Votes

I'd still check memory, but that really seems like a startup time issue to me. After you deleted the initial sideloaded app and then pushed a new version, the watch would have needed to recompile the code prior to running it. If that takes 10+ seconds, Bad Things can happen. SDK3 code seems to take longer to compile on the watch than does SDK 1 or 2 code.

 

I'd check memory before doing anything drastic.

Peter McLennan
Gondwana Software
Best Answer
0 Votes

Thanks - I'll follow your suggestions and report back...

Best Answer
0 Votes

I just added lines to check memory on startup and then every second in the clock loop.  With SDK3 I get

 

Pasted Graphic.jpg 

I let it run for a few minutes and it seems to hover around 41-43k.  So I think ti is the startup time rather than memory.  

Best Answer
0 Votes

I agree. I'm currently throwing together a FAQ on SDK development. Here's a foretaste:

 

Spoiler

Don't initialise anything you don't have to immediately. For example, initialise elements for secondary screens only when they’re about to be displayed. If you structure such code into objects, you can also reduce memory use.

getElementById(), getElementsByClassName(), etc, can be quite slow. If your .gui is large but well structured, minimise calls to document.getElementById by using the element’s immediate parent, rather than ‘document’, if there are several elements beneath that parent. This will spare the startup code from having to look through the whole DOM every time.

 

This is a big job. Before getting carried away with it, it might be wise to comment out some chunks of code, variables and/or UI elements that aren't initially required, just to verify the hypothesis (and maybe narrow down focus areas).

Peter McLennan
Gondwana Software
Best Answer
0 Votes

Thanks - I look forward to seeing your end product!

 

In the meantime my immediate problem has been solved since an SDK2 build of Clarity has just been approved and released.

 

However I will plug away at this and see what I can do following your suggestion of commenting out sections.

Best Answer
0 Votes

It's fixed!  In the end the key was exactly what you suggested - namely to minimise calls to document.getElementById by using the element’s immediate parent.   It now sideloads comfortably...

 

Pasted Graphic.jpg

I still have to try loading it from the gallery but I am sure it will now be fine.

 

Thanks again for taking the time to help.  I really appreciate it!

Best Answer

Excellent! I'm relieved that I didn't send you on a wild goose chase.

 

I haven't noticed any performance or behaviour differences when loading from debug bridge vs. gallery, so you should be fine I think.

Peter McLennan
Gondwana Software
Best Answer
0 Votes