I am developing a rather large application, which I am testing in emulation until I feel it is ready for pushing it on an Android device.
The app architecture is spread out over several screens which seem to all work, except one. 3 of those screens are quite complex, and two of them do run as expected, but the 3rd one is giving me trouble, with the emulator "stalling" on load, which ends with an emulator crash.
For a while I suspected that perhaps the presence of tables (which seemed to have caused a problem in another screen, since then corrected by replacing the table arrangements with a multi-layered organization of nested horizontal and vertical arrangements) was to blame for it, so I cleaned it up. The duplicate screen with no table arrangements loaded and displayed fine in the emulator, until I imported the computing procedures. Then it crashed.
At that point in time, all those procedures were still unconnected to any event trap, so loading the page would not have activated them. But I presume the system provisionally visits them on page load (even before the ".Initialize" runs) to allocate memory and resources; is that a valid assessment?
It so happens that this is indeed the most complex screen in terms of sheer size and number of blocks, with something like a projected total 160 sel-contained Blocks (definitions, event traps and called procedures), which should represent about 3500 statement-blocks. The other screens that currently load and run fine each have about 2500 statement-blocks total.
That is a lot, but is it really *too much*?
I dread having to split this screen into two less complex screens, since it would affect the harmony and feel of the application; but if there is no other way... I would like to know if there are alternative approaches that could be tried before launching myself in a major reprogramming effort that I do not know would be successful (since splitting the code will end up making two components that are each 60 to 65% of the original combined screen, as some functions would have to be duplicated, and could still be beyond the limit, if there is such a limit in the first place).
Has anyone come across an actual "memory space saturation" of that (suspected) sort, and could share experience and gained wisdom in that area?
Thanks
CBVG
--
I tested your app and in this case the issue is that the screen layout is so complex that it is causing the companion to run out of memory. Because the emulator covers devices back to Android version 1.5, it is limiting processes to 16 MB of RAM. Most new Android devices will allow for 32 MB or more of RAM per process. I used the companion on a Samsung Galaxy S4 and was able to load all of your screens without issue because it allows the process 128 MB of RAM. It is possible that there are ways of optimizing the companion code so that these more complicated screens will work in the emulator, but that will take some time and effort on our part. In the meantime, if you can get your hands on an Android phone and test using the companion, that will be your best opportunity to finishing your app.
Evan
--
Well, "teaching tools" is a bit of a stretch. It could have started like that, but does not have to still be called only that. For the record, the first programming language I learned -- that was in 1975 -- was Pascal. Back then, it was touted as a teaching language, but don't tell that it is ONLY a teaching environment to all the people building real life application in Lazarus/Free Pascal or Delphi.
My basic point is that there are limitations to the emulator which I do not know are representative of some of the most limited devices out there, as far as the number of blocks is concerned; but those limitations are not explicitly documented, hence the issue. As I built the app, and the list of requirements and features grew, I did consider moving the whole project to a different environment. However, that would mean essentially giving up of about 1000 hours of work and starting from scratch, while pressing forward could be just a few weeks away, as long as the limitations can be addressed through some tweaking.
Still, the problem was not an issue of debugging, but of system interface and resources allocation. I think that I made that clear from the get go, as the code was not running, and could not even be made to run as it lacked the calls to the procedures from the still missing even traps; but was only trying to load, on one of the screens.
I feel that my experience will prove invaluable to whoever comes after and tries similar developments, I am just surprised that I seem to be the first one to ever do this (mind you, I have a tendency to "stretch the envelope". When that Atari Portfolio came out in 1989, it was stated that one would not use it to type the "next great american novel". But I did write a full length novel on this--on-lookers may debate whether it qualifies as a "next great american novel", particularly since it is science fiction, and most of it is set in space, but I digress).
I take good note of this "google time out" issue. This is another thing that perhaps should be posted somewhere prominent, as opposed to being found only in forum response. That said, the application is not intended to be CPU intensive. One would be expected to enter data and get an answer from it in the course of less than one minute, perhaps once or twice a week. The problematic screen is supposed to offer database edition capability, to revisit and potentially correct previously entered data, and is not expected to be run even that infrequently; performance is not as paramount as reliability and data visibility.
Thanks for the insight.
CBVG
--
Now that is what I call a *good* answer.
Yes, the application is complex, and from a philosophical point of view, does need to cater to any devices, including the ones most limited in memory (right up to Cupcake, if need be)
You claim that you tested my app? How did you manage to access it? Aren't those supposed to be linked to a google mail account, and thus locked?
It is reassuring to learn that the emulator is representative of the weakest type of Android device, this indeed would serve as a demonstration that if it does run there, then it will run everywhere. On the flip side, relying on my own Marshmallow Android device, I would quite possibly have been totally oblivious to the limitations others may have, taking liberties that would make it not as portable as it should. Hence my insistance to rely on the emulator (unless someone has a vintage Cupcake device for sale, cheap?)
I did a bit of soul searching, and will likely end up splitting the problematic screen in two. That screen had dual modes, using a button click to toggle between them and relying on "visibility" to change the display appropriately, so might not be too much of a problem to work-out, although my sensitivity to code optimisation would be hurt by the need to duplicate some procedures in both screen (unless I find a clever way of invoking the call to an auxiliary screen that serves no other purpose than running those procedures which does not end up taking even more resources for said page switching).
Thanks for your help and insight.
CBVG
--
Hi Vincent,
There are several things here that we should address. First, you have a complex app and need to help. Evan's answer is right on the money you should try this and see if that helps finsh your app. BTW we are currently working on a solution with regards to updating the emulator and allowing more features. But, in the meantime head Evan's suggestions. Second, I think you realize that their are complex apps that touch the outer bounds for App Inventor and therefore often suits the space of Teaching Tool, with Ghica and Taifun suggestions and best practices most of our community has been having a lot of success. To finish we are continuing to refine, update and enhance App Inventor and our communities experiences.
Best,
Andrew McKinney
Director of Software Development
MIT App Inventor Project
--
I would like to know if there are alternative approaches that could be tried before launching myself in a major reprogramming effort that I do not know would be successfu
If you want another straw to grasp, look into sending some of your application complexity into a Web Viewer via Javascript files in the Media drawer.
There might be a structural cost in working around a delay in getting results back from the Web Viewer
Good luck with your app!
ABG
--
Intriguing... That could be a clever solution. On my side, the downside is that this is Javascript, which is not a language I master. I would have to consider the time to get familiar with the specifics of that language.
That said, if the number crunching activity is passed on to a web viewer component, does this imply that said web viewer will then have a memory foot-print that has to be taken into consideration?
CBVG
--
1- This was not confusing to ME, it was confusing to YOU, that is why YOU brought up this irrelevant point
3- I know what I am doing, I am what you would call a "seasoned" programmer. I am new only to App Inventor. If I say there is virtually no redundancy, take it as a given. And given the complexity of the app, passing "screenshots" of the all the blocks from the problematic screen page would need at least 15 screen captures (after reorganizing to maximize coverage), at maximum zoom-out, where everything is microprint. Trust me, you don't want to go there.
4- Seems to me the consensus is that there is; some processing has to go somewhere else to lighten the load on that screen
5- If it is not relevant (which is precisely why I mentioned it) why did YOU bring up that topic?
-- I feel that the key issue is "how many bocks is too much", not "when you have too much, you have too much", which I already pretty much had figured out. What is needed is some metric that would say something like 3000 blocks total on a screen is usually OK, while 3200 probably not (or whatever values it should be). That is the kind of info that would be practical, reliable, and useful.
--
Intriguing... That could be a clever solution. On my side, the downside is that this is Javascript, which is not a language I master. I would have to consider the time to get familiar with the specifics of that language.
Another AI2 user recently posted a new AI2-Javascript sample here
It computes the hypotenuse of a right triangle, given the two non-diagonals sides lengths.
The sample should you an idea of the amount of boiler plate needed to get into Javascript's math capabilities,
how to pass multiple inputs across the AI2/WebViewer interface,
how to force a pause for the Web Viewer to do is work,
anf how to retrieve the calculation output.
Though I've been scared away from diving into my phone-book sized Javascript book,
I find that AI2 sample clear, even in a foreign language.
That said, if the number crunching activity is passed on to a web viewer component, does this imply that said web viewer will then have a memory foot-print that has to be taken into consideration?
I have no data on that. I assume you won't need more than one Web Viewer component, since you can feed it different html pages from your Media drawer and different dynamic input. The Blocks Editor and Designer can't possibly be affected by the contents of what appear to them as extra files in the Media Drawer. Only the Web Viewer sees them, at run time, as your blocks feed them into the Web Viewer.
Again, this just a straw to grab, under the general category of "Turn Blocks into Data"
ABG
--
(Throwing more stuff at the wall in hope something sticks...)
Under the category of "Turn Blocks into Data", here's another idea for how to reduce the component and blocks count in an app with a lot of input fields.
(I haven't seen your app, so I'm guessing here.)
Think of how your data would be represented in JSON.
JSON lets you encode all your app's data in a structured text string.
The attribute names, bracket nesting and element grouping can be summarized in a JSON schema,
that summarizes the structure of the data and that can be used to drive the capture of such data from a user,
a field at a time, into a nested AI2 list-of-pairs structure.
You probably don't need to package your data into JSON strings for interchange over the Web,
but having the schema on hand can help a small number of input components (a single label and text box) be re-used
(probably under a ListView showing the current data level's elements and values)
to fill in your data structure.
For an example of such a structure, see this sample doc, based on XML:
(The doc only shows how to parse and navigate the data, not how to build it up.)
You could trade off navigating nested lists for looking up TinyDB data using concatenated tags/subtags.
This refactoring of your input would save you on components,
at the expense of having to code a little schema-driven input presenter and gatherer.
Unfortunately, I don't have a sample for you.
If you're unfamiliar with multi-level data navigation, see this sample:
ABG