json from resource

1. There is no documentation only one example...

2. It's from 2.3 CIQ but for all device?

3. How it works?

-  what is returned from loadResource(resourceId_jsonres)? dictionary?

- memory usage. After loading json_res in function to local var is memory released after exiting from func? or happens something like with string_res - memory is occupied until app exit?

  • 2. It's from 2.3 CIQ but for all device?

    Not all devices support CIQ 2, so no. For example, old devices like Fenix 3, FR230, 920XT and Vivoactive (original) only support CIQ 1.

    -  what is returned from loadResource(resourceId_jsonres)? dictionary?

    It depends on what your JSON resource contains, as you might guess from the example:

    - A JSON array is mapped to a monkey c array

    - A JSON object is mapped to a monkey c dictionary

    - A JSON primitive (string, number or boolean) is mapped to the corresponding monkey c primitive

    - memory usage. After loading json_res in function to local var is memory released after exiting from func? or happens something like with string_res - memory is occupied until app exit?

    Well, as we talked about many times before, when you load a resource, it's not the resource itself that stays in memory forever, it's the resource table (where each entry is just some kind of constant-sized reference to a resource -- maybe 4 bytes each? I forget.)

    So it works just like a string resource: if you load a JSON resource into a local variable, the memory for the *resource* itself is freed, but as soon as you call loadResource() for the first time, the resource table is loaded into memory and stays there forever, which sucks if you have lots of resources (regardless of the size of their contents), like application settings strings.

    This is something you could test pretty easily tho.

    So this means that in some cases, even if you move some data to JSON resources, you may end up losing more memory because the resource table stays in memory. (This assumes that you aren't already calling loadResource() for some other reason. If you already have to load resources, then using JSON resources is always a win.)

    I agree that there should be better documentation. I can't even find where it says JSON resources are only for CIQ 2 and above, although I know it's true.

  • 1. If compile app with minimum sdk 2.4 everybody who takes app can use json_res?

    2. ok

    3, so if have only one json-res in memory remain only one id but not all data connected with it, yes? I I've tried to make null on rez.string with exception of course:-)

    https://developer.garmin.com/connect-iq/core-topics/resources/

    JSON data resources can store relatively large amounts of data in your app without having to keep it in memory at all times. This can be useful for storing something like a table of information that must be referenced at runtime, but will not be modified.

    I need this data only ones to build another data so I plan to do somewhere on the beginning (onStart, initialise etc.) when there is no a lot of object in memory. So there is a big chance to success.

  • 1. If compile app with minimum sdk 2.4 everybody who takes app can use json_res?

    Yes, as far as I know.

    Do you have some reason to believe that support would be missing for a given device which has the minimum required CIQ version? If I knew about something like that, I would've said it in my original answer.

    3, so if have only one json-res in memory remain only one id but not all data connected with it, yes? I I've tried to make null on rez.string with exception of course:-)

    The whole resource table (with all the IDs) will stay in memory. It's going to be more than one ID because you also have to have at least one string for the app name. If you have app settings, then you have to have at least one string resource for each setting. If you have FIT contributor data, then you have string resources for each label.

    Again, as I said above, if you are already reading resources (sounds like you are), then this part doesn't matter as you already have to load the resource table. I just brought it up because I've had an app which doesn't use resources, but had a decent amount of hardcoded data in an array. I moved the array to a JSON resource, but it ended consuming more memory, because the size of the resource table was actually bigger than the size of the code for the data, since I had a number of strings for application settings. Which is why I'm still pretty annoyed that app setting strings are needlessly included in the app resource table.

    Like I said, it's just like any other resource as far as memory goes. (With the exception of bitmap resources in CIQ 4).

  • 1. there is no documentation for json so it possible like in many situation (e.g ft55 doesn't support metersClimbed that is from 2.1 and fr55 has 3.x). it rather shouldn't happen because it's system matter.

    2. can you say that when I'm loading font resources table for json is also loaded to the memory? good that only small portion of it,

    after some tests I've saved 5kb  so it's good.

    settings - no way it's out of control you have to put labels into rez.strings but for rest I've found some tricks to optimise it - a few kb too:-)

  • 1. there is no documentation for json so it possible like in many situation (e.g ft55 doesn't support metersClimbed that is from 2.1 and fr55 has 3.x). it rather shouldn't happen because it's system matter.

    If you look carefully at the list of supported devices for ActivityInfo.metersClimbed and read between the lines, you'll see that it's only supported for devices that have a barometric altimeter. For example, FR735XT and FR245 also lack support for metersClimbed, because they also lack a baro.

    In the case of JSON resources, there's no sane reason for some devices to exclude support. Even Garmin doesn't hate us that much.

    2. can you say that when I'm loading font resources table for json is also loaded to the memory? good that only small portion of it,

    Yep. One call to loadResource() loads all the resource tables (with numerical resource IDs only) into memory, permanently.

    Just to prove my point, I modded a data field app of mine which has a bunch of resources and changed it so it just loads one JSON resource and exits. Look at how much memory is wasted by string IDs - and my app only uses strings for settings.

    But why take my word for it? Just try it for yourself.

    I've said this so many times, but I don't understand why Garmin didn't just create a separate resource table for app setting strings, so it doesn't have to be loaded by the app on watch, at runtime. Maybe Garmin does hate us a little bit, especially since it seems that they could make this change at any time, and in such a way that even the oldest watch could benefit, since it can all be done at compile-time.

    after some tests I've saved 5kb  so it's good.

    Cool

  • How do you know that jsonData is supported from CIQ 2.3? I don't see any mention of that in https://developer.garmin.com/connect-iq/core-topics/resources/ or in the documentation: developer.garmin.com/.../WatchUi.html

  • I seemed to remember it being a compiler error message, but maybe I saw it in the docs somewhere. But yes jsondata as a resource isn't supported in CIQ 1. I use / parse strings to get the same effect.

  • How do you know that jsonData is supported from CIQ 2.3? I don't see any mention of that in https://developer.garmin.com/connect-iq/core-topics/resources/ or in the documentation: developer.garmin.com/.../WatchUi.html

    The JsonDataResources SDK sample specifies minSdkVersion as 2.3.0. If you try to build a project containing JSON resources for an unsupported device, the compiler will spit out an error message such as:

    JSON resources are not supported by device 'fr235'.

    I wish stuff like this was explictly documented, too, but apparently Garmin prefers folk knowledge to be continuously rediscovered by trial and error, or propagated through the forums. I also think Garmin doesn't care too much about older devices.

  • Yeah, the problem is that not only it's not documented, there's also no way to check it either in build time or in run time (using has doesn't help as it uses the same loadResource that exists on every device)

  • Well you can always hardcode the list of devices which don't support JSON resources (which you would have to do anyway, if you want to include CIQ 1 devices in a project that has JSON resources for all supported devices.)

    It's a pain but at least you can be (fairly) sure the list will never change (similar to hardcoding the list of CIQ 1 devices themselves.)

    (Yes, I realize there's an exception with the Garmin Swim 2, which was released after the CIQ 1 era but nonetheless only supported CIQ 1. Ofc that one is an unusual case in that it only supports CIQ watch faces, and not any other CIQ app types.)