tag:blogger.com,1999:blog-1318720439107983572024-03-14T03:11:28.328+00:00The simple Virtual lifejoshttp://www.blogger.com/profile/03322746770159735235noreply@blogger.comBlogger80125tag:blogger.com,1999:blog-131872043910798357.post-68782582816711146122021-09-12T17:51:00.002+01:002021-09-12T17:51:47.707+01:00Managing multiple versions of Java locally: SDKMAN to the rescue!<p>I wanted to try the newly added <a href="https://blog.jetbrains.com/idea/2021/03/java-16-and-intellij-idea/" target="_blank">Records</a> to Java 16, mostly because I immediately had the feeling that they would be pretty much the same as Kotlin <a href="https://kotlinlang.org/docs/data-classes.html" target="_blank">data classes</a>. As it turns out, they are pretty similar but have certain <a href="https://medium.com/codex/the-difference-between-kotlins-data-classes-and-java-16-records-7e25fdbcb50d" target="_blank">differences</a>, but that is not the point of this entry.</p><p>As I work on projects that still depend on Java 8, I couldn't just simply upgrade my version of Java. Luckily I have been using <a href="https://sdkman.io/" target="_blank">SDKMAN</a> on my machine, even though I initially did not have a reason to do so, but as it happens, the new setup for my tests was rather straight forward.</p><p>Adding a new version of Java is just a matter of running the following command (in my case to add Java 16):</p><p><span style="font-family: courier;">sdk install java 16.0.1.hs-adpt</span></p><p>And to use it you can:</p><p><span style="font-family: courier;">sdk use java 16.0.1.hs-adpt</span></p><p>But it is a bit of a pain to have to run the 'use' command every time you want to work on that project. The solution is to add a config file in the root folder of your project called `.sdkmanrc`. This is the content of my config file:</p><div style="text-align: left;"><span style="font-family: courier;">>cat .sdkmanrc<br /># Enable auto-env through the sdkman_auto_env config<br /># Add key=value pairs of SDKs to use below<br />java=16.0.1.hs-adpt</span></div><p>Finally, if you want the version in the rc file to run automatically when you cd into a particular project you can set this up in the overal sdkman config file, which on mac is at `~/.sdkman/etc/config`. There you can change the default `false` value of the following property to true:</p><p><span style="font-family: courier;">sdkman_auto_env=true</span></p><p>You can do a lot more with SDKMAN, but this was exactly what I needed for the particular tests I had in mind. Enjoy!</p>joshttp://www.blogger.com/profile/03322746770159735235noreply@blogger.comtag:blogger.com,1999:blog-131872043910798357.post-69436886304265924232017-10-31T12:35:00.001+00:002021-09-10T22:48:29.045+01:00A very brief intro to Machine Learning for DevelopersLast Saturday we ran a <a href="https://www.tensorflow.org/" target="_blank">TensorFlow</a> codelab at the <a href="https://twitter.com/GDGDublin" target="_blank">GDG Dublin</a> <a href="https://twitter.com/search?f=tweets&vertical=default&q=devfest17&src=typd" target="_blank">devfest17</a>. We worked through the <a href="https://codelabs.developers.google.com/codelabs/tensorflow-for-poets-2/" target="_blank">tensorflow for poets</a> codelabs after a short intro to machine learning concepts, targeted towards developers, and with the only goal of making sure that the concepts in the codelabs could be correctly understood. Here are the slides from the event:<br />
<br />
<iframe allowfullscreen="true" frameborder="0" height="299" mozallowfullscreen="true" src="https://docs.google.com/presentation/d/e/2PACX-1vSFxist1Gur1hhBSyBrtQpbav3jn7vkgkpW14HHO7M3aa_T-8Jv1HfQPVErY_LHSe-RAKLT69rhMPJv/embed?start=false&loop=false&delayms=30000" webkitallowfullscreen="true" width="480"></iframe><br />
<br />
The devfest was a blast, as usual; looking forward to next year already!<br />
<br />joshttp://www.blogger.com/profile/03322746770159735235noreply@blogger.com0tag:blogger.com,1999:blog-131872043910798357.post-50967679479159406672016-11-24T12:35:00.001+00:002016-11-24T12:35:30.394+00:00Some talks and papers for 2016It's been a really busy end quarter of the year, and in the last few months I got around to publishing one paper, and doing a number of presentations.<br />
<br />
Back in September I was lucky enough to travel to beautiful <a href="https://en.wikipedia.org/wiki/Krak%C3%B3w" target="_blank">Kraków</a> in Poland to talk about data science and IoT-ish stuff at <a href="http://devday.pl/" target="_blank">DevDay16</a>.<br />
My talk was titled '<b><i>A Homespun Decentralised DIY Data Science Research Pipeline for the Internet of *Your* Things</i></b>' (quite a mouthful!), and it basically relates my adventures in the last year, trying to move from a software development background into a more data science oriented view of the world. I also rant about privacy for quite a while.<br />
<br />
These are the slides and recording of the talk:<br />
<br />
<script async="" class="speakerdeck-embed" data-id="227eae6cc3104990bcd57544babf8053" data-ratio="1.33333333333333" src="//speakerdeck.com/assets/embed.js"></script><br />
<br />
<iframe allowfullscreen="" frameborder="0" height="315" src="https://www.youtube.com/embed/V-8PfhU-HT4" width="560"></iframe><br />
<br />
The conference was fantastic, flawlessly organised, and they treat speakers incredible well. You should definitely consider their CFP next year!<br />
<br />
In October I got the chance to present at the <a href="http://2016.splashcon.org/track/mobile2016#program" target="_blank">Mobile!16</a> workshop at SPLASH in Amsterdam. My paper is about requirements for mobile health applications, with an <a href="https://en.wikipedia.org/wiki/End-user_development" target="_blank">End User Development</a> flavour to it, provided by App Inventor. The paper can be found <a href="http://dl.acm.org/citation.cfm?doid=3001854.3001856" target="_blank">here</a>, and the slides are:<br />
<br />
<script async="" class="speakerdeck-embed" data-id="ae3f20957cb94961b8ee90bcc66c4164" data-ratio="1.33333333333333" src="//speakerdeck.com/assets/embed.js"></script><br />
<br />
<br />
Finally in November I gave another talk at the PyCon Ireland conference, this time about image classification in Python. During the summer a group of people helped me collect pictures of food, with a view to figure out some way of classifying the contents. There are a few companies out there such as <a href="https://clarifai.com/" target="_blank">Clarifai</a> and <a href="https://indico.io/" target="_blank">Indico</a> that do a pretty good job at classification and tagging of images (Google and Microsoft also have very good vision products, but I didn't want to go down that path). Their APIs are pretty nice and easy to use, but I wanted to figure out if I could locally reproduce at least some of the results they provide. My first attempt was to do classification with a technique called '<a href="http://www.cs.unc.edu/~lazebnik/spring09/lec18_bag_of_features.pdf" target="_blank">bag of features</a>', which I must say, didn't work incredible well in complicated pictures such as food. After that I followed today's trend of using deep learning (everybody is at it!), more concretely using TensorFlow to retrain the Inception model that Google made available at some point last year. Results, as you can imagine, are much better, even if I can't really explain any of the math behind it!<br />
<br />
The title of the talk was '<b><i>Introduction to Image Classification in Python: from APIs to Neural Networks</i></b>', and here you can find my slides (recordings are not available yet):<br />
<br />
<script async="" class="speakerdeck-embed" data-id="9f9f86eed55e409cb7f36f739b592b02" data-ratio="1.77777777777778" src="//speakerdeck.com/assets/embed.js"></script><br />
<br />
Oh, and I also got a chance to finally go to the Mozilla Festival in October. We run a session about <a href="https://github.com/mozillascience/PaperBadger" target="_blank">Paper Badger</a>, but I'll tell you all about it in a different post!<br />
<br />joshttp://www.blogger.com/profile/03322746770159735235noreply@blogger.com0tag:blogger.com,1999:blog-131872043910798357.post-73244845228127183572014-10-08T18:24:00.001+01:002015-03-25T14:08:59.709+00:00App Inventor dev tricks: reducing compilation time while doing developmentI want to share a few tricks that some of us use for speeding up App Inventor when we are full on development mode. Note that most of these tricks should only be used while developing, but when you are ready to open a pull request you should skip all tricks, make a full compilation for all languages and browsers, and fully test (manually as much as you can, and always run `ant tests`).<br />
<br />
The first thing you should check (at least from time to time) is the listing of available targets in the main ant script. Here is how:<br />
<br />
<b><i>Tip 1: check out all targets available with `ant -p` from time to time.</i></b><br />
<br />
At this particular time, it looks like the following:<br />
<br />
<code>
appinventor-jos$ ant -p<br />
Buildfile: ~/appinventor/build.xml<br />
Other targets:<br /><br />
AIMergerApp<br />
Blockly<br />
BlocklyTest<br />
PlayApp<br />
RunLocalBuildServer<br />
all<br />
clean<br />
comps<br />
installplay<br />
javadoc<br />
noplay<br />
tests<br /><br />
Default target: all
</code>
<br />
<br />
As you can see, there are a number of targets here, but in this post I will only go into the ones I consider that save time during development. The following are only recommendations, you do not have to do this, of course!<br />
<br />
Also consider that if you see a new target being added, make sure you understand how to use it because it can save you some time in the long run.<br />
<br />
<b><i>Tip 2: avoid using `ant clean` whenever you can.</i></b><br />
<br />
Compiling App Inventor is done incrementally, so only what's needed to be compiled will be compiled. Unfortunately, the GWT part of the system takes literally <b><i>ages</i></b> when a full compilation needs to happen (see Tip 6 for more on this). If you are making changes in that part of the system, you are kind of stuck with a full compilation, but it does not mean you need to <i>clean</i> all the time.<br />
<br />
The clean target does not only delete all the compiled files, but also deletes all your projects, so <i>use with caution</i>. When would you use clean, then? Well, if things start to get weird, like rare errors you haven't seen before, or compilation errors that do not seem to appear in your IDE, then it's time to clean. Another good indication of <i>cleaning time</i> is if you change branches that contain incompatible code. But if you can avoid this, there are a number of other targets that can help you out. Let's see some of them.<br />
<br />
<b><i>Tip 3: When in Blocky Land, do as the Blocklians do.</i></b><br />
All the App Inventor Blockly related code gets compiled into a single file called <i>blockly-all.js</i> that you will find in your <i>build</i> folder. If you are making JavaScript changes (and only in the /blocklyeditor or lib/blockly files) you can rebuild this file by calling `ant Blockly` (note the Capital B). No other files need rebuilding (generally), and this target takes time in the order of seconds and not minutes! Make sure you check out tip 4 to see how to reload this file without restarting the main server.<br />
<br />
<b><i>Tip 4: There's no need to restart the main server --- most of the time!</i></b><br />
Most times there is no need to restart the app engine server. By disabling caching in your browser(s) and reloading the project, all should be good to go.<br />
You can disable caching in Chrome Dev tools or in Firefox (probably in Safari too!).<br />
<br />
In Firefox, go to '<i>Tools --> Web Developer --> Developer Toolbar</i>' and click on the wrench icon at the end of the toolbar, at the bottom of the page. The toolbar will enlarge and then you can click on a gear icon for settings. Scroll down to 'Advanced Settings' and you will see an option like the one in the following figure:<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://4.bp.blogspot.com/-0iA-EcPl5mA/VRLBFnD1ZvI/AAAAAAAAA34/xasW1Y9L67M/s1600/disable_cache_firefox.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="http://4.bp.blogspot.com/-0iA-EcPl5mA/VRLBFnD1ZvI/AAAAAAAAA34/xasW1Y9L67M/s1600/disable_cache_firefox.png" height="228" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Disabling cache - Firefox</td></tr>
</tbody></table>
<br />
<br />
In <i>Chrome Dev Tools</i> you simply need to click on the gear icon for settings and you will see something similar to the next figure:<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://2.bp.blogspot.com/-ImU-97wXPtM/VRLBSSEwUVI/AAAAAAAAA4A/U7zwDyKRGNI/s1600/disable_cache_chrome.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="http://2.bp.blogspot.com/-ImU-97wXPtM/VRLBSSEwUVI/AAAAAAAAA4A/U7zwDyKRGNI/s1600/disable_cache_chrome.png" height="224" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;"><span style="font-size: 12.8000001907349px;">Disabling caching - Google Chrome</span></td></tr>
</tbody></table>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
Note that disabling cache only applies when you have the dev tools open, so you don't have to worry about your normal web surfing with this setting.<br />
<br />
<b><i>Tip 5: Component changes might not need a full build</i></b><br />
UNLESS you change the signature of a method (in blocks this can be a method or event signature, or a property), you will not need to reflect those changes in the designer, so there's no need to build the GWT part of the system.<br />
<br />
When no changes to the designer are needed, you can use `ant comps`, which will not only compile exclusively changes to your component, but will also push a freshly baked App Inventor Companion app to your phone if you have it connected through USB.<br />
<br />
<b><i>Tip 6: Minimize permutations in GWT compilation</i></b><br />
There are two ways of minimizing the number of compilations that GWT will run during a full build, one being restricting the number of browsers you build for, and the second being the number of languages you fully build. These changes can be made in the <a href="https://github.com/mit-cml/appinventor-sources/blob/master/appinventor/appengine/src/com/google/appinventor/YaClient.gwt.xml">YaClient.gwt.xml</a> file.<br />
<br />
If you generally develop only using Chrome, or Safari, or Firefox, you can modify the GWT config file to avoid building for other browsers. In line 10 in the following gist, in the value for <i>user.agent</i> you can choose between 'safari' and 'gecko1_8'. If you generally only use firefox, you can delete everything before the comma (including the comma). If you generally use chrome or safari, keep the safari value and delete the comma and the gecko part. This will compile GWT only for the browser you have chosen.<br />
<br />
Since we have introduced the internationalization code, the more languages we add, the longer it takes to build (more permutations of the code). In the gist again, if you comment out lines 104 to 109, both included, you will only build the interface in English.<br />
<br />
You can combine languages and browser and go down to 2 permutations instead of 9, which will save several minutes from your build.<br />
<br />
<script src="https://gist.github.com/josmas/bc4870118b359cbae67c.js"></script>
<b><i>Tip 7: Do you really need that build server running all of the time?</i></b><br />
This isn't really a compilation tip, but it might also save you time while developing.<br />
Some people use a starting script that runs both the app engine server and the build server. Most of the time (note, not all of the time!) you will be making a bunch of changes and testing them on the companion if they are component changes, or in the browser if they are interface changes. You will only build an apk towards the end of the process (in component changes) before submitting a pull request. So you won't need to spin up the build server most of the time.<br />
<br />
<b>NOTE</b><br />
As mentioned at the top of this post, please note that most of these tips are to be used only during development, <b><i>BUT</i></b> before you open a pull request, you should test fully, and with all languages and all browsers.<br />
<br />
Happy (and hopefully shorter) building!<br />
<br />
<br />
<br />
<br />joshttp://www.blogger.com/profile/03322746770159735235noreply@blogger.com1tag:blogger.com,1999:blog-131872043910798357.post-72319971932544793072014-07-24T18:15:00.001+01:002014-07-24T18:15:11.564+01:00Support for building apps on API Level 4 in App Inventor - Better Tablet SupportWe've been working to take <a href="http://appinventor.mit.edu/explore/">App Inventor</a> out of <i>screen compatibility mode</i>, and that work has now been <a href="https://github.com/mit-cml/appinventor-sources/commit/369188912ec963e4dbae7248d170f0ed362f8720">merged</a>. This hasn't made it to a release yet, but it will soon. We will announce the changes in the forums when this happens.<br />
<b><br /></b>
<b>What does it all mean though?</b><br />
For starters, App Inventor will not support Android 1.5 (API level 3 - Cupcake) anymore, but we are compiling against Android 1.6 (API level 4 - Donut). We know there aren't a lot of devices out there still working at this level, but the change from level 3 to 4 was a rather large step to take, mainly because of the already mentioned <a href="http://developer.android.com/guide/practices/screen-compat-mode.html">screen compatibility mode</a>.<br />
<br />
Up to now, all App Inventor apps would be automatically scaled by the system to make them look <i>the same</i> in all devices, no matter their resolution or screen size. This sounds good, but the effect of this was that most elements would look rather awfully oversized on bigger screens such as tablets. From now on, the <i>resolution</i> of the device will be used, and apps will look much better in larger screens with higher resolutions. As a drawback, the App Inventor designer will be a bit less in sync with what's actually being rendered on the device, but we've done our best to keep things as smooth as possible. If you find any issues with rendering in the designer please do get in touch with us <a href="https://groups.google.com/forum/#!forum/mitappinventortest">through the forum</a>.<br />
<br />
<b>What other changes have been made?</b><br />
We have added a check to change from Tablet to Phone preview mode. It basically resizes the viewer so that you can see how the app looks at two different sizes. We are using Nexus sizes as generic here, Nexus4 for phone, and Nexus7 for tablet. As you can see in the screenshot below, we have also added the buttons bar found in most newer devices. The two changes are highlighted in red.<br />
<div class="separator" style="clear: both; text-align: center;">
<span id="docs-internal-guid-bfadb751-6930-594c-75bd-d668e8363be1" style="margin-left: 1em; margin-right: 1em;"><br /><img height="506px;" src="https://lh6.googleusercontent.com/mbg8ZtPDGhwVPa6O6K-kLNAXm-2GjIFOXxlO2GkKy6uKtps7he6C_ebadfl9WMe0vDFoShjeZ3OtF56LyxoSxbM71foRvwSElxGLCN2fozSmZoyXKMroa7IOsKBlv-vkTA" style="-webkit-transform: rotate(0rad); border: none;" width="306px;" /></span></div>
<br />
Another big change is that now all sizes for elements are <b><i>density-independent pixels</i></b> (DP) instead of hardcoded pixels. You will see a change in the Width and Height boxes in the designer.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<span style="font-family: Arial; font-size: 15px; margin-left: 1em; margin-right: 1em; vertical-align: baseline; white-space: pre-wrap;"><img height="139" src="https://lh6.googleusercontent.com/GYT7L6Mi33Bc2Fuy0cIglw4r71DemPiHygR4rgweFKFnNizf4-3hNAV_7byC1LFWEhDeC6RbsGp7XIEmTaZIXaGR9J2iP85oNFav6DHJY0b39gP5NWpxVD2AsTz7PB3LDw" style="-webkit-transform: rotate(0rad); border: none;" width="200" /></span></div>
<span id="docs-internal-guid-15eaf362-6930-a803-d7cd-6ce75f90b277"></span><br />
<br />
The concept of DP is a little hard to grasp. Some people compare it to using percentages for sizes in HTML, but that's not quite correct. This is the definition used in the main <a href="http://developer.android.com/guide/practices/screens_support.html">Android docs</a>:<br />
<br />
<div dir="ltr" style="line-height: 1.2954545454545454; margin-bottom: 0pt; margin-top: 0pt;">
<code><span style="background-color: #f9f9f9; color: #222222; font-family: Roboto; font-size: 15px; font-style: italic; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Density-independent pixel (dp)</span></code></div>
<code>
</code>
<br />
<div dir="ltr" style="line-height: 1.2954545454545454; margin-bottom: 8pt; margin-left: 23pt; margin-top: 0pt;">
<code><span style="background-color: #f9f9f9; color: #222222; font-family: Roboto; font-size: 15px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">A virtual pixel unit that you should use when defining UI layout, to express layout dimensions or position in a density-independent way. <br />
The density-independent pixel is equivalent to one physical pixel on a 160 dpi screen, which is the baseline density assumed by the system for a "medium" density screen. At runtime, the system transparently handles any scaling of the dp units, as necessary, based on the actual density of the screen in use. The conversion of dp units to screen pixels is simple: </span><span style="background-color: #f9f9f9; color: #006600; font-family: Roboto; font-size: 13px; vertical-align: baseline; white-space: pre-wrap;">px = dp * (dpi / 160)</span><span style="background-color: #f9f9f9; color: #222222; font-family: Roboto; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;">. For example, on a 240 dpi screen, 1 dp equals 1.5 physical pixels. You should always use dp units when defining your application's UI, to ensure proper display of your UI on screens with different densities.
</span></code></div>
<br />
This DesignBytes video by Roman Nurik is a good source of information about the topic:<br />
<br />
<iframe allowfullscreen="" frameborder="0" height="315" src="//www.youtube.com/embed/zhszwkcay2A" width="560"></iframe><br />
<br />
<br />
There is an additional property that has also been added to Images: <b><i>scaleToFit</i></b>; checking this box you can make an image fit completely the size of its enclosing area, for instance if you fill the parent in width or height, the image will fit the area (the image will not keep its aspect ratio, so be mindful when using this property).<br />
<br />
<br />
So, with all these changes, <b>what are the things to watch out for?</b><br />
Some apps might be affected, especially those using hardcoded sizes in pixels. We have made many tests and the majority show very little differences, but there might still be some differences.<br />
The other thing to watch out for is if you were using any tricks to grab the height and width of the screen to size your elements. Watch out for problems in there and please report whatever you find.<br />
<br />
<b><i>And what's next then?</i></b> Well, this change opens a number of possibilities for App Inventor apps. We can start thinking about using a targetSDK level now, even providing a property in Screen1 to allow the user to choose which level that is. We could also start thinking about moving to API Level 8 (Froyo) as there are not many devices using a level lower than that. But probably the most important change here is that we can now start using <i>support libraries</i> and think about adding some of the most used <i>design patterns</i> in Android, such as Action Bar, navigation patterns, or even themes.<br />
<br />
This is all a bit far ahead, but there's no technical reason stopping us now from working on changes like those. If you want to help with any of these projects, do get in touch through the <a href="https://groups.google.com/forum/#!forum/app-inventor-open-source-dev">open source forum</a>. Great times ahead!joshttp://www.blogger.com/profile/03322746770159735235noreply@blogger.com4tag:blogger.com,1999:blog-131872043910798357.post-66423131604271653952014-06-20T03:41:00.001+01:002014-06-20T03:41:56.377+01:00Software Engineer / Research position - MIT App InventorThe <a href="http://appinventor.mit.edu/appinventor-sources/">MIT App Inventor team</a> is looking for a software engineer with interest in research in education, and, of course, open source.<br />
You can find more information in this <a href="https://groups.google.com/d/msg/app-inventor-open-source-dev/xc0QG_k1Au8/0AIr1Y6gBFgJ">thread</a>. If you want to know a little more about what we do, you can keep on reading this blog, or ping me on <a href="https://twitter.com/josmasflores">twitter</a> and I'll be happy to talk to you.<br />
<br />
What are you waiting for to apply? do it... now!joshttp://www.blogger.com/profile/03322746770159735235noreply@blogger.com1tag:blogger.com,1999:blog-131872043910798357.post-75991734189749259162014-06-02T04:25:00.001+01:002014-06-02T04:32:28.039+01:00Random Hacks of Kindness Boston 2014The fine folks of the <a href="http://www.meetup.com/Code-for-Boston/">Boston brigade</a> of <a href="http://codeforamerica.org/">Code for America</a> have done it again... a fantastic weekend full of hacking, delicious food, and awesome projects!<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://tonywebster.com/wp-content/uploads/2013/06/national-day-of-civic-hacking-transparent-png-logo.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="72" src="https://tonywebster.com/wp-content/uploads/2013/06/national-day-of-civic-hacking-transparent-png-logo.png" width="400" /></a></div>
<br />
This was also part of the kickoff of the <a href="http://hackforchange.org/">National Day of Civic Hacking</a> competition, but back to Boston, you can find tons of information in the <a href="https://codeforboston.hackpad.com/RHoK-Boston-Hack-the-Hub-NDoCH-2014-May-31-June-1-hackforchange-ikZwrCUBuxc">event's hackpad</a>.<br />
<br />
Here though, I'm going to write a little about the project I was involved in, <a href="http://unioncapitalboston.com/">Union Capital Boston</a>. The main idea is to create a system of rewards, similar to the typical restaurant or coffee shop loyalty cards, but in which people accumulate points through good deeds in their communities. This is targeted to individuals and families within lower income brackets, so that they can exchange points for things that can help them make ends meet, such as groceries or travel passes.<br />
<br />
<iframe allowfullscreen="" frameborder="0" height="281" mozallowfullscreen="" src="//player.vimeo.com/video/96044859" webkitallowfullscreen="" width="500"></iframe>
<br />
On the tech side, the main app is being built on <a href="https://www.meteor.com/">meteor</a>. To be honest, I didn't have a lot of time to form an opinion about how meteor works, but the one thing that took me by surprise is that being a node framework, it has its own package manager, and things are a bit confusing (sometimes you load packages from meteor, sometimes from atmosphere, and there's some support for npm??? dunno, I'm confused!).<br />
<br />
I spent most of the Saturday trying to push the meteor app into a <a href="http://cordova.apache.org/">Cordova app</a>. After many hours fighting with a few different solutions I found on the net, it turned out that the wifi we were using wouldn't allow two devices to talk to each other; so most of my time was spent trying to <i>fix the unfixable</i>. On Saturday night I arrived home, compiled the app without changing a thing, and it all worked. On Sunday back at <a href="http://greentownlabs.org/">GreenTown Labs</a>, it wouldn't work again. In any case, you can check out the app in my github repo at <a href="https://github.com/josmas/UCapp">UCapp</a>. The <i>readme</i> file also documents all the research I went through on Saturday, and some failed attempts. You can find the main UC Boston app at <a href="https://github.com/drenfr01/unionCapital">Duncan's repo</a>, and a lot more information in our <a href="https://codeforboston.hackpad.com/Union-Capital-Boston-sDmj0ZU33ow">project's hackpad</a>.<br />
<br />
It was great to meet new people and see some old friends that I hadn't seen in a while. Looking forward to the next meetup (and hackathon) already!
<br />
<blockquote class="twitter-tweet" lang="en">
Closing <a href="https://twitter.com/search?q=%23RHoKboston&src=hash">#RHoKboston</a> <a href="https://twitter.com/carpeliam">@carpeliam</a> and <a href="https://twitter.com/_beechnut">@_beechnut</a> <a href="http://t.co/Ta11CcAIqO">pic.twitter.com/Ta11CcAIqO</a><br />
— Jos (@josmasflores) <a href="https://twitter.com/josmasflores/statuses/473228689002741762">June 1, 2014</a></blockquote>
<script async="" charset="utf-8" src="//platform.twitter.com/widgets.js"></script>joshttp://www.blogger.com/profile/03322746770159735235noreply@blogger.com0tag:blogger.com,1999:blog-131872043910798357.post-1115157405839163952014-05-28T02:29:00.002+01:002014-05-28T15:39:06.776+01:00App Inventor 2 - Translation ComponentIn a <a href="http://josmasflores.blogspot.com/2014/05/note-for-developers-about-new.html">previous post</a> I talked about the new <a href="http://ai2.appinventor.mit.edu/reference/components/media.html#YandexTranslate">Yandex.Translate</a> component that we added to <a href="http://appinventor.mit.edu/">App Inventor</a> 2 about a week ago. In this video you can see how to use it.<br />
<br />
<iframe allowfullscreen="" frameborder="0" height="315" src="//www.youtube.com/embed/T9O6stYSDUQ" width="560"></iframe><br />
<br />
Make sure you don't tamper with the Yandex note in the <i>About this App</i> Screen as it is a <a href="http://api.yandex.com/translate/doc/dg/concepts/design-requirements.xml">design requirement</a> stated in the terms of use of the Yandex.Translate service.<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-BDk9n19zNF4/U4DD97tUaxI/AAAAAAAAAnc/Hj5UDsonldE/s1600/YandexAbout.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://3.bp.blogspot.com/-BDk9n19zNF4/U4DD97tUaxI/AAAAAAAAAnc/Hj5UDsonldE/s1600/YandexAbout.png" /></a></div>
joshttp://www.blogger.com/profile/03322746770159735235noreply@blogger.com3tag:blogger.com,1999:blog-131872043910798357.post-25956436413702540202014-05-26T15:44:00.001+01:002014-05-26T15:44:38.564+01:00Breaking changes for DatePicker in App Inventor 2We've decided to to push a breaking change to our production server, which is something we very rarely do. The reason was that some <i>Java style thinking</i> leaked into one of the components, the <a href="http://ai2.appinventor.mit.edu/reference/components/userinterface.html#DatePicker">DatePicker</a>.<br />
<br />
When I wrote that component I was <i>obviously thinking about something else</i>, and I broke one of the most distinctive abstractions that we use in <a href="http://appinventor.mit.edu/">App Inventor</a>: all our sequences are 1-based and not 0-based. Newcomers to programming find this a lot easier to grasp. Because Java returns month numbers on a 0-based array, I went with that and our Month attribute returned 0 for January and 11 for December.<br />
Because the component has not been out for long, we have decided that it's better to change it now and take the heat than leaving this leaked abstraction hurting our users.<br />
<br />
More info in this <a href="https://groups.google.com/d/msg/mitappinventortest/cQZJPiE6IjQ/ZkY6tZDL3H8J">announcement</a> in the forums, and I've added an annotation to the <a href="http://josmasflores.blogspot.com/2014/05/date-and-time-pickers-in-app-inventor-2.html">video and post</a>. This break will only affect you if you are still working on an app that uses this component, or if you want to upgrade an app that you programmed in the last week, and you were using some type of correction to counteract the fact that the sequence was 0-based. Otherwise, it should not affect you (we are hoping this affects to only a few developers).<br />
<br />
Apologies for this breaking change; it is something that should never happen (again!).joshttp://www.blogger.com/profile/03322746770159735235noreply@blogger.com1tag:blogger.com,1999:blog-131872043910798357.post-39218098194092885672014-05-24T17:12:00.000+01:002014-05-24T17:12:14.757+01:00Note for developers about the new translation component in App Inventor 2We have recently added a translation component based on the <a href="http://api.yandex.com/translate/">Yandex.Translate</a> service.<br />
<br />
This service needs an API key to work, and as you can imagine, we have not pushed that into the repo. In fact, we cannot circulate that key, so if you are creating your own distribution of <a href="http://appinventor.mit.edu/">App Inventor</a> or simply running your own server from the MIT repository, you will have to add that key to the source code before you compile the system.<br />
<br />
This is an easy thing to do; once you have created a Yandex account, you can <a href="http://api.yandex.com/key/form.xml?service=trnsl">request a key</a>. After that, paste that key in the <a href="https://github.com/mit-cml/appinventor-sources/blob/master/appinventor/components/src/com/google/appinventor/components/runtime/YandexTranslate.java">component</a>.<br />
<br />
<pre class="prettyprint"> public YandexTranslate(ComponentContainer container) {
super(container.$form());
// Set up the Yandex.Translate Tagline in the 'About' screen
form.setYandexTranslateTagline();
// TODO (user) To provide users with this component you will need to obtain
// a key with the Yandex.Translate service at http://api.yandex.com/translate/
yandexKey = "";
activity = container.$context();
}
</pre>
<br />
The place to paste it is in the yandexKey string available in the constructor, as shown in the code above. The instructions in the TODO are rather explicit.<br />
<br />
And that would be all if you think that all your users will not generate enough traffic to go over the limits of a particular key. If that is not the case, I would recommend to modify the component to allow your users to add their own keys when creating apps. This is what we do in some other components such as <a href="https://github.com/mit-cml/appinventor-sources/blob/master/appinventor/components/src/com/google/appinventor/components/runtime/Twitter.java">Twitter</a> or <a href="https://github.com/mit-cml/appinventor-sources/blob/master/appinventor/components/src/com/google/appinventor/components/runtime/FusiontablesControl.java">FusionTables</a>.<br />
<br />
Also note that this component, when being used, adds some information to the <i>About</i> screen in the app:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-BDk9n19zNF4/U4DD97tUaxI/AAAAAAAAAnY/Sz8AFbZEOgU/s1600/YandexAbout.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://2.bp.blogspot.com/-BDk9n19zNF4/U4DD97tUaxI/AAAAAAAAAnY/Sz8AFbZEOgU/s1600/YandexAbout.png" /></a></div>
<br />
This is a <a href="http://api.yandex.com/translate/doc/dg/concepts/design-requirements.xml">design requirement</a> that is mandatory to use the service. If you decide to tamper with that, or you have disabled the <i>About</i> screen, I would recommend to find another solution to keep this requirement or you will be breaching the terms of use for the service.joshttp://www.blogger.com/profile/03322746770159735235noreply@blogger.com1tag:blogger.com,1999:blog-131872043910798357.post-83298614257843918462014-05-19T14:15:00.002+01:002014-05-19T14:15:23.874+01:00App Inventor 2 Spinner componentA <a href="http://developer.android.com/guide/topics/ui/controls/spinner.html" target="_blank">Spinner in Android</a> provides a quick way to choose from a set of options. We have added a Spinner to <a href="http://appinventor.mit.edu/" target="_blank">App Inventor 2</a>, and it's super easy to use. Have a look at the following video to find out how.<br />
<br />
<iframe allowfullscreen="" frameborder="0" height="315" src="//www.youtube.com/embed/JLCLcU05FRc" width="560"></iframe>joshttp://www.blogger.com/profile/03322746770159735235noreply@blogger.com5tag:blogger.com,1999:blog-131872043910798357.post-80523429500823310032014-05-19T14:11:00.001+01:002014-05-19T14:11:51.456+01:00App Inventor 2 ListView componentThe existing ListPicker allows to generate a series of choices to let the user decide which one to choose; for this, it creates a new Screen (or activity). The new ListView component works in the same way, with an almost identical API, but it does not create an additional screen, so you can embed your data within the Screen you are working on. The following video explains the basics of ListView in <a href="http://appinventor.mit.edu/" target="_blank">App Inventor 2</a>.<br />
<br />
<iframe allowfullscreen="" frameborder="0" height="315" src="//www.youtube.com/embed/hlQNxmp87Ts" width="560"></iframe><br />
<br />
<br />joshttp://www.blogger.com/profile/03322746770159735235noreply@blogger.com0tag:blogger.com,1999:blog-131872043910798357.post-74981832784897698832014-05-19T14:06:00.000+01:002014-05-26T15:30:27.901+01:00Date and Time pickers in App Inventor 2<b>IMPORTANT UPDATE:</b> <b><i>There has been an upgrade to the Component and now it returns 1 = January and 12 = December for the Month property</i></b>.<br />
<br />
We have added two very simple widgets to <a href="http://appinventor.mit.edu/" target="_blank">App Inventor 2</a> (note they won't be added to App Inventor 1, but if you cherry pick the commit to the AI1 branch, it should work too). Date picker and Time picker are really easy to use, as you can see in this video:<br />
<br />
<iframe allowfullscreen="" frameborder="0" height="315" src="//www.youtube.com/embed/UbA3pDQALKY" width="420"></iframe>joshttp://www.blogger.com/profile/03322746770159735235noreply@blogger.com0tag:blogger.com,1999:blog-131872043910798357.post-8754604062301981302014-05-18T07:30:00.000+01:002014-05-18T07:30:00.779+01:00MIT App Inventor: Enabling Personal Mobile ComputingA few months ago Shay Pokress and I <a href="http://arxiv.org/abs/1310.2830" target="_blank">submitted a paper</a> for the PROMOTO2013 workshop at SPLASHCONF13. The paper got accepted and I got to go to Indiana to do a tool demo for <a href="http://appinventor.mit.edu/" target="_blank">App Inventor</a> and present a poster too. This is the slide deck used at the conf:<br />
<br />
<script async="" class="speakerdeck-embed" data-id="45f2bf10becc0131474566935fc535a5" data-ratio="1.77777777777778" src="//speakerdeck.com/assets/embed.js"></script>joshttp://www.blogger.com/profile/03322746770159735235noreply@blogger.com0tag:blogger.com,1999:blog-131872043910798357.post-6603426095917808162014-05-17T09:30:00.000+01:002014-05-20T03:18:46.654+01:00App Inventor - Related ResearchThis is another slide deck from an <a href="http://www.eecs.mit.edu/academics-admissions/academic-information/subject-updates-ft-2013/6s198" target="_blank">MIT 6.S198</a> lecture, this time about EdTech in general, and more specifically about the many research influences that <a href="http://appinventor.mit.edu/" target="_blank">App Inventor</a> and other similar systems share.<br />
<br />
<script async="" class="speakerdeck-embed" data-id="f03e4780bec90131f63f5665d8eb8aa4" data-ratio="1.77777777777778" src="//speakerdeck.com/assets/embed.js"></script><br />
<br />
If you want to know more about the class, feel free to browse (and use, reuse, redistribute, improve, and so forth!) the materials linked from the class' <a href="https://docs.google.com/document/d/1Rmiq5h33NyFsakoUJgli8pVj5A1ilPD9klf_yU64hEs/edit?usp=sharing" target="_blank">calendar</a>.joshttp://www.blogger.com/profile/03322746770159735235noreply@blogger.com0tag:blogger.com,1999:blog-131872043910798357.post-17316428767313604832014-05-16T02:42:00.000+01:002014-05-16T02:42:03.728+01:00JavaScript for Developers @MIT 6.S198 - Fall 13As part of the <a href="http://www.eecs.mit.edu/academics-admissions/academic-information/subject-updates-ft-2013/6s198" target="_blank">App Inventor class</a> we run last semester at MIT, I prepared (or I should say rehashed, cause I had used this same material before for training) this presentation about JavaScript for developers familiar with other programming languages.<br />
<br />
<script async="" class="speakerdeck-embed" data-id="d09b7040bec70131ae3766fdbbb32492" data-ratio="1.33333333333333" src="//speakerdeck.com/assets/embed.js"></script><br />
<br />
If this is of interest to you, you can consult the calendar and all materials for the class <a href="https://docs.google.com/document/d/1Rmiq5h33NyFsakoUJgli8pVj5A1ilPD9klf_yU64hEs/edit?usp=sharing" target="_blank">here</a>.joshttp://www.blogger.com/profile/03322746770159735235noreply@blogger.com0tag:blogger.com,1999:blog-131872043910798357.post-20803351649033930872014-04-24T18:51:00.001+01:002014-04-24T18:52:57.497+01:00Sharing component for App InventorWe released a new <a href="http://ai2.appinventor.mit.edu/reference/components/social.html#Sharing" target="_blank">Sharing</a> component about a week ago, and I recorded a rough and ready video for it. It uses and Android <a href="http://developer.android.com/reference/android/content/Intent.html" target="_blank">Intent</a> to share information (a message or a file, or both) with other apps that are ready to handle the data provided.<br />
<br />
<iframe allowfullscreen="" frameborder="0" height="315" src="//www.youtube.com/embed/fCdxtYj09Zw" width="420"></iframe><br />
<br />
We had to iron out a few things, such as paths coming from other components like the <a href="http://ai2.appinventor.mit.edu/reference/components/media.html#ImagePicker" target="_blank">ImagePicker</a> or the <a href="http://ai2.appinventor.mit.edu/reference/components/media.html#Camera" target="_blank">Camera</a>. We also had to deal with the fact that the dialog would come up really big for certain actions, and on certain devices. We have a fix for all of that, and it's on review right now, but will soon be in our <a href="https://github.com/mit-cml/appinventor-sources" target="_blank">github repo</a>; it might take a bit longer to go live (next release for sure, but we don't know right now when that is happening).joshttp://www.blogger.com/profile/03322746770159735235noreply@blogger.com4tag:blogger.com,1999:blog-131872043910798357.post-12301431678222803732013-06-21T16:21:00.000+01:002013-06-21T16:21:45.707+01:00Open Source Development with App Inventor: Part 6 : Wrapping Up Series 1<blockquote class="tr_bq">
Show <a href="http://josmasflores.blogspot.com/search/label/open%20source%20with%20app%20inventor" target="_blank">all videos</a> of this series.</blockquote>
Part 6 of <i>Open Source Development with <a href="http://appinventor.mit.edu/appinventor-sources/" target="_blank">App Inventor</a></i> will be the last video that I'm going to record for now. Most of the basics have been covered, so I have decided to take a break from videos, and probably go back to writing more focused posts. In any case, don't expect much from me until the end of the summer!<br />
If you have any topics that you'd like me to cover, and think it's worth making a video of it, please leave a comment.<br />
<br />
The last couple of hangouts have been focused on the part of App Inventor that, in my opinion, is the most technically interesting: how incremental development happens in the <a href="http://en.wikipedia.org/wiki/Read%E2%80%93eval%E2%80%93print_loop" target="_blank">REPL</a>, which for us can either mean the emulator, or a connected device (via USB or wifi). I know little about that part, so I guess that's why I find it so interesting. If you want to know more about incremental development, you cannot miss out watching the hangout in May, in which <a href="http://jis.qyv.name/" target="_blank">Jeff</a> talks about it, and also about the rendezvous server used with the Companion app(wifi mode). The video is here:<br />
<br />
<iframe allowfullscreen="" frameborder="0" height="315" src="http://www.youtube.com/embed/dq3XJzOusNo" width="560"></iframe><br />
<br />
For more information on how Java interoperation is achieved through Kawa, the June hangout should help:<br />
<br />
<iframe allowfullscreen="" frameborder="0" height="315" src="http://www.youtube.com/embed/WYxf-zoJn4A" width="560"></iframe><br />
<br />
There are a number of very important topics for App Inventor development, and I briefly cover some of them in the video. Please use the mailing list for discussion, ranging from ideas or improvements, to stickier topics such as what the primary audience for App Inventor is, should the focus shift towards other targets, and so on.<br />
There's been a number of new distributions appearing (if you follow the forums, you can see the work Hossein, Gary, or Dave Wolber are doing). These are all great, but it would also be great if, as a community, we can talk about how to best approach things and design for interoperability. A couple of good examples in the forums are the threads about the <a href="https://groups.google.com/forum/#!searchin/app-inventor-open-source-dev/sqlite/app-inventor-open-source-dev/UAyC54Im_do/fdwj5ptqPToJ" target="_blank">sqlite component</a>, and a discussion titled <a href="https://groups.google.com/forum/#!searchin/app-inventor-open-source-dev/fragmentation/app-inventor-open-source-dev/292hsNN1kn0/KxkjFZRQ6MwJ" target="_blank">the dangers of fragmentation</a>. Please keep active in the forums and irc.<br />
<br />
The last subject in this video briefly covers how to work with <b>App Inventor 2</b> (codename: <b><i>newblocks</i></b>) from the github account.<br />
<br />
And finally, here's the video for Part 6:<br />
<br />
<iframe allowfullscreen="" frameborder="0" height="315" src="http://www.youtube.com/embed/pVoR_D3pUik" width="420"></iframe><br />
<br />
<br />
Enjoy!joshttp://www.blogger.com/profile/03322746770159735235noreply@blogger.com2tag:blogger.com,1999:blog-131872043910798357.post-7704106010162513132013-06-15T16:37:00.000+01:002013-06-15T16:37:46.144+01:00Open Source Development with App Inventor: Part 5 : Your own Personal Companion<blockquote class="tr_bq">
Show <a href="http://josmasflores.blogspot.com/search/label/open%20source%20with%20app%20inventor" target="_blank">all videos</a> of this series.</blockquote>
In this part of the video series we are going to see how to package our own Companion app. This is the app that can be used with wifi for development purposes (no USB cable needed).<br />
<br />
<br />
<iframe allowfullscreen="" frameborder="0" height="315" src="http://www.youtube.com/embed/rsJ8w7oUIF4" width="420"></iframe><br />
<br />
<br />
As explained in the video, the reason why you would want to create your own app is that the Companion contains a copy of each of the Components available in the system. If you develop a new component, this new guys and its blocks will not be available in an app distributed by MIT. You can create your own app by using an ant target available in the main build script:<br />
<br />
<b><span style="font-family: Courier New, Courier, monospace;">ant PlayApp</span></b><br />
<br />
Make sure that you manually uninstall any other Companion apps before installing the newly created one, especially if you have installed an app distributed by MIT. The reason is that the apps, even though they can have the same name, are going to be signed with different keys, and the phone might get a bit confused.<br />
<br />
<br />
If for any reason you need a Companion app for an older version of App Inventor, you can create one using the MIT repo git <a href="https://github.com/mit-cml/appinventor-sources/tags">tags</a>. One thing I forgot to mention in the video is that to update the tags from the repo, you have to fetch them. This can be done by executing (assuming you have called the remote '<i>upstream</i>'):<br />
<br />
<span style="font-family: Courier New, Courier, monospace;"><b>git fetch upstream</b></span><br />
<br />
These are the steps to move to a different commit (in this case we use a tag, but a commit would work too), and create the new-old Companion app:<br />
<br />
0. make sure you are in clean state, in master, and with all the
latest from upstream (mit-cml)<br />
1. sync with upstream to grab all the tags: <span style="font-family: Courier New, Courier, monospace;"><b>git fetch upstream</b></span><br />
2. checkout the tag you want to build the companion for: <span style="font-family: Courier New, Courier, monospace;"><b>git checkout v133</b></span><br />
- this will put you in detached head mode<br />
3. <span style="font-family: Courier New, Courier, monospace;"><b>ant clean; ant; ant PlayApp</b></span><br />
- this creates: MIT Companion app.apk<br />
4. <span style="font-family: Courier New, Courier, monospace;"><b>git co master</b></span> to go back to master.<br />
<br />
And that is all for this video, catch you in the next one!joshttp://www.blogger.com/profile/03322746770159735235noreply@blogger.com0tag:blogger.com,1999:blog-131872043910798357.post-13776701319152427772013-06-08T15:47:00.000+01:002013-06-08T15:47:06.240+01:00Open Source Development with App Inventor: Part 4 : Android Activity Lifecycle<blockquote class="tr_bq">
Show <a href="http://josmasflores.blogspot.com/search/label/open%20source%20with%20app%20inventor" target="_blank">all videos</a> of this series.</blockquote>
The <a href="http://developer.android.com/training/index.html" target="_blank">training</a> site for Android is full of great resources. If you have an interest in Android development, I would recommend to go through all of the sections, but if your time is limited and you can only go through a bunch of them, you should not skip <a href="http://developer.android.com/training/basics/activity-lifecycle/index.html" target="_blank">Managing the Activity Lifecycle</a>.<br />
<br />
Always keep the following figure in mind when developing and app, and <a href="http://appinventor.mit.edu/appinventor-sources/" target="_blank">App Inventor</a> provides hooks to the Activity Lifecycle through the <a href="https://github.com/mit-cml/appinventor-sources/blob/master/appinventor/components/src/com/google/appinventor/components/runtime/Form.java" target="_blank">Form</a> class:<br />
<br />
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: left; margin-right: 1em; text-align: left;"><tbody>
<tr><td style="text-align: center;"><a href="http://developer.android.com/images/training/basics/basic-lifecycle.png" imageanchor="1" style="clear: left; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" src="http://developer.android.com/images/training/basics/basic-lifecycle.png" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Activity Lifecycle, from Android training site.</td></tr>
</tbody></table>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
The following video shows those hooks, and the main interfaces used to that effect:<br />
<br />
<br />
<iframe allowfullscreen="" frameborder="0" height="315" src="http://www.youtube.com/embed/GK2YhfVgCMo" width="420"></iframe><br />
<br />
<br />
In the next video we will be showing how to package the Companion app from sources, and explaining why you would want to do that in first place.joshttp://www.blogger.com/profile/03322746770159735235noreply@blogger.com0tag:blogger.com,1999:blog-131872043910798357.post-34034685231517963692013-05-29T21:23:00.001+01:002013-05-29T21:23:03.768+01:00Open Source Development with App Inventor: Part 3 : Read the source Luke<blockquote class="tr_bq">
Show <a href="http://josmasflores.blogspot.com/search/label/open%20source%20with%20app%20inventor" target="_blank">all videos</a> of this series.</blockquote>
Welcome to another video of the Open source development with App Inventor series. In part 3 we will go through the sources by reviewing how new Components are created. We will see some of the main parts of the <a href="https://github.com/mit-cml/appinventor-sources/blob/master/appinventor/components/src/com/google/appinventor/components/runtime/Twitter.java" target="_blank">Twitter</a> component, and what parts of the system need changing to make sure that everything is kept in sync.<br />
<br />
The image that opens the video was taken from <a href="http://www.codinghorror.com/blog/2012/04/learn-to-read-the-source-luke.html">Coding Horror</a>, a fantastic blog about software development.<br />
<br />
<iframe allowfullscreen="" frameborder="0" height="315" src="http://www.youtube.com/embed/YHMmSo2sX5o" width="560"></iframe><br />
<br />
The main two documents used in this video are:<br />
<ul>
<li><a href="https://docs.google.com/document/pub?id=1xk9dMfczvjbbwD-wMsr-ffqkTlE3ga0ocCE1KOb2wvw" target="_blank">How to add a Component</a></li>
<li><a href="https://docs.google.com/document/pub?id=14c1X19s6pXYHdDBOJJELcmOghWbm2FPekRvGzX0ENps" target="_blank">How to add a Property to a Component</a></li>
</ul>
<br />
In the next video we will be talking a little bit about the Android lifecycle, how it affects App Inventor apps, and how the codebase hooks into the methods provided by the Android SDK. Catch you then!joshttp://www.blogger.com/profile/03322746770159735235noreply@blogger.com6tag:blogger.com,1999:blog-131872043910798357.post-32933704482502891932013-05-20T13:40:00.001+01:002013-05-23T03:25:50.732+01:00Open Source Development with App Inventor: Part 2 : Working with the Sources and Git<blockquote class="tr_bq">
Show <a href="http://josmasflores.blogspot.com/search/label/open%20source%20with%20app%20inventor" target="_blank">all videos</a> of this series.</blockquote>
In this part of the <i>Open Source Developement with App Inventor</i> series, we'll see how to work with the sources. My first (and only) attempt at recording it was getting too long, so I decided to divide this part in several videos (3 in total).<br />
<br />
In the first video (titled <b><i>Part 2</i></b>), we'll see the documents that are the base of all the actions explained in the video. These are mainly two, <a href="https://docs.google.com/document/pub?id=1Xc9yt02x3BRoq5m1PJHBr81OOv69rEBy8LVG_84j9jc">How to build App Inventor from MIT sources</a>, and <a href="https://docs.google.com/document/d/1ow0b5dcQrR5XktunOF5dFPMf_ctZdnQxtneqRiR2zFs/pub">Developing App Inventor with git and github</a>. As mentioned in the video, if you just want to run App Inventor locally, and do not expect to be changing the sources at all, then the first document is enough. If you want to work a bit on the sources, make some changes, or create your own components, then you need to read both documents. And here is the first video:<br />
<br />
<iframe allowfullscreen="" frameborder="0" height="315" src="http://www.youtube.com/embed/M3j0aVqBGL0" width="420"></iframe><br />
<br />
In the second video (titled <b><i>Part 2 and a Half</i></b>), we see how to sync with the <b><i>remote</i></b> or <b><i>upstream</i></b> repository. Git is a <a href="http://en.wikipedia.org/wiki/Distributed_revision_control">distributed version control system</a>. If you have worked with a system like subversion before, Git might be a bit difficult to grasp at the beginning. Here's a good comparison article between <a href="http://blogs.atlassian.com/2012/02/version-control-centralized-dvcs/">centralised and distributed</a> source control. If you haven't gone through the Git resources highlighted in previous videos of this series, please do so now. In this video we will see how we can get our github <b><i>Fork</i></b> synchronised with the <a href="https://github.com/mit-cml/appinventor-sources">main repository</a> maintained by the MIT team.<br />
<br />
<iframe allowfullscreen="" frameborder="0" height="315" src="http://www.youtube.com/embed/erfMs6TRmYE" width="420"></iframe><br />
<br />
The third video (titled <b><i>Part 2 and Three Quarters</i></b>) shows how, once the sources have been built, the system can be locally launched. As explained in previous videos of this series, there are two main servers that you need to get running to play with App Inventor locally, one is the server portion of the <b><i>appengine</i></b> project that backs the <b style="font-style: italic;">Designer</b> interface, and the other one is the <b><i>Build Server</i></b> that creates the apk files for your projects. Here's how you can do that:<br />
<br />
<iframe allowfullscreen="" frameborder="0" height="315" src="http://www.youtube.com/embed/8_btQNOFkuA" width="420"></iframe><br />
<br />
<br />joshttp://www.blogger.com/profile/03322746770159735235noreply@blogger.com0tag:blogger.com,1999:blog-131872043910798357.post-84662676339657158682013-05-08T16:48:00.001+01:002013-05-23T03:25:06.134+01:00Open Source Development with App Inventor: Part 1 : Developer Overview<blockquote class="tr_bq">
Show <a href="http://josmasflores.blogspot.com/search/label/open%20source%20with%20app%20inventor" target="_blank">all videos</a> of this series.</blockquote>
In this second part of the video series we are going to explore the basics of the system, at a very high level. A description of the different projects and what they do is given.<br />
<br />
<iframe allowfullscreen="" frameborder="0" height="315" src="http://www.youtube.com/embed/V2oiXrKR5EM" width="420"></iframe><br />
<br />
The links for this part are:<br />
<br />
<div class="p2" style="background-color: white; color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 15px; line-height: 20px;">
<b>Where to find stuff?</b></div>
<div class="p2" style="background-color: white; color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 15px; line-height: 20px;">
<span class="s1"><b>Main OSS Website:</b></span> http://appinventor.mit.edu/appinventor-sources/</div>
<div class="p2" style="background-color: white; color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 15px; line-height: 20px;">
<span class="s1"><b>Forum:</b></span> https://groups.google.com/forum/#!forum/app-inventor-open-source-dev</div>
<div class="p2" style="background-color: white; color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 15px; line-height: 20px;">
<span class="s1"><b>IRC Channel:</b></span> freenode.net #appinventor</div>
<div class="p2" style="background-color: white; color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 15px; line-height: 20px;">
<br /></div>
<div class="p2" style="background-color: white; color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 15px; line-height: 20px;">
<b>Other links:</b></div>
<div class="p2" style="background-color: white; color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 15px; line-height: 20px;">
<a href="https://docs.google.com/document/pub?id=1hIvAtbNx-eiIJcTA2LLPQOawctiGIpnnt0AvfgnKBok">App Inventor Developer Overview</a></div>
joshttp://www.blogger.com/profile/03322746770159735235noreply@blogger.com2tag:blogger.com,1999:blog-131872043910798357.post-67744776152663356262013-05-02T06:17:00.000+01:002013-05-23T03:23:35.251+01:00Open Source Development with App Inventor: Part 0<blockquote class="tr_bq">
Show <a href="http://josmasflores.blogspot.com/search/label/open%20source%20with%20app%20inventor" target="_blank">all videos</a> of this series.</blockquote>
I am a big fan of tech video series. If I recall correctly, <a href="http://railscasts.com/">railscasts</a> was the first one I watched, probably at about the same time that I started following <a href="http://www.ted.com/talks">TED talks</a> (although the latter are not really a 'series' in itself, and not always about tech). Much more recently, I have very thoroughly enjoyed the <a href="http://angularjs.org/">AngularJS</a> videos in <a href="http://www.egghead.io/">egghead.io</a>, and I tend to watch as many full conferences as I can.<br />
<br />
No surprises here then if I tell you that I have started recording my own series, right? The topic is <a href="http://appinventor.mit.edu/explore/">App Inventor</a> and Open Source. I have no idea how often I'll get a chance to record a video, but if you want me to talk about an specific part of the project, I'll do my best to get it online. I will always try to keep them shorter than 10 minutes (that's the format I generally enjoy more), so some topics will be divided into multiple videos. I do not intend to do any editing, so at times, you'll see me doing some weird stuff and getting it all wrong, but I won't be cutting stuff off, mostly for the sake of learning. Feel free to shout to the screen (as I do... at times...) or leave a comment, and I'll do my best to get it right in another video.<br />
<br />
I am going to start with the basics, but this isn't really a 'Learn Java' kind of series; there are millions of resources out there to learn Java and Android, so I doubt we need yet another one (and I also doubt I can do a better job!). So if you know a bit of Java (or some other language), and you are familiar with the command line, and building programs from it, you are all set for the series... so let's get started!<br />
<br />
<b>Part 0: Before you start</b><br />
<iframe allowfullscreen="" frameborder="0" height="315" src="http://www.youtube.com/embed/pR8bRvK7zsU" width="420"></iframe><br />
<br />
Here are the links in the video:<br />
<br />
<div class="p2">
<b>Where to find stuff?</b></div>
<div class="p2">
<span class="s1"><b>Main OSS Website:</b></span> http://appinventor.mit.edu/appinventor-sources/</div>
<div class="p2">
<span class="s1"><b>Forum:</b></span> https://groups.google.com/forum/#!forum/app-inventor-open-source-dev</div>
<div class="p2">
<span class="s1"><b>IRC Channel:</b></span> freenode.net #appinventor</div>
<div class="p2">
<br /></div>
<div class="p2">
<b>Other links:</b></div>
<div class="p2">
</div>
<div class="p1">
Article about the <a href="http://lifehacker.com/5633909/who-needs-a-mouse-learn-to-use-the-command-line-for-almost-anything">command line</a>.</div>
<div class="p1">
Github and CodeSchool <a href="http://try.github.io/">interactive tutorial</a>.</div>
<br />joshttp://www.blogger.com/profile/03322746770159735235noreply@blogger.com1tag:blogger.com,1999:blog-131872043910798357.post-72679277731568298422013-04-24T14:28:00.000+01:002013-04-25T02:05:41.175+01:00Long running tasks in App Inventor Components<i>(Many thanks to Mark Friedman from Google for his review and great comments).</i><br />
<br />
<div class="p1">
As mentioned in the post about the <a href="http://josmasflores.blogspot.com/2013/02/a-single-thread-of-execution-in-app.html"><span class="s1">UI thread</span></a>, App Inventor is basically a UI centric system, in the sense that everything happens within a <b><i>Screen</i></b>. For this reason, when tasks that might take a bit of time to finish are required, they should be done in their own thread, or otherwise the full UI will come to a halt until the task finishes up.</div>
<div class="p2">
<br /></div>
<div class="p1">
Examples of long running tasks could be, among others, any operations that need access to external resources, such as the calls in the Web component, the calls to the Twitter API, calls to reading from the SD card, sending or retrieving data in TinyWebDB calls, and so on.</div>
<div class="p2">
<br /></div>
<div class="p3">
So how can these kind of operations be dealt with? Mainly by dividing the process into two stages, a first part that spins a new thread to deal with the operation itself, and a second part that can trigger an event back in the UI thread, once the operation is finished. This is the core idea behind <b><i>Event-Driven Architectures</i></b> or <b><i>Event-Driven Programming</i></b>, and most toolkits for creating graphical interfaces use it widely.<br />
<br />
<div class="p1">
According to Wikipedia, <a href="http://en.wikipedia.org/wiki/Event-driven_programming"><span class="s1">Event-driven Programming</span></a> can be defined as:</div>
<blockquote class="tr_bq">
<i>[...] an application architecture technique in which the application has a <a href="http://en.wikipedia.org/wiki/Main_loop"><span class="s1">main loop</span></a> which is clearly divided down to two sections:</i>
<br />
<ul>
<li><i>the first is event selection (or event detection)</i></li>
<li><i>the second is event handling.</i></li>
</ul>
</blockquote>
<div class="p3">
Let’s see it with a concrete example; Think about how the <a href="https://github.com/mit-cml/appinventor-sources/blob/master/appinventor/components/src/com/google/appinventor/components/runtime/Web.java"><span class="s1">Web</span></a> component in App Inventor works:<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><img height="269px;" src="https://lh5.googleusercontent.com/7zWbOzEOWJZciBdUX6oDM323ONno9Btd2OmzGpWrv75ThAANSZmgbzS3OdQ7aLKC1n--T2gXxKWodkzEKA6Rk8VHGwZGWlo5dtT7GV1Y-VlESXxy8SvDHvo8dA" style="margin-left: auto; margin-right: auto;" width="475px;" /></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Part 1: Call Get : Part 2: when GotText gets triggered, handle it.</td></tr>
</tbody></table>
<div class="separator" style="clear: both; text-align: center;">
<b id="docs-internal-guid-53e7fe6d-3c2b-5ba7-4bc7-a7b35736325a" style="font-weight: normal; margin-left: 1em; margin-right: 1em;"></b></div>
<br />
<div class="p1">
The user will place a <b><i>Web.Get</i></b> call block in a handler(such as a button click), and configure the component with the URL to be accessed. That is part 1 of our event-driven design. For part 2, the user needs to place a <b><i>Web.GotText</i></b> event block (or Web.GotFile) in the blocks editor, and they are assured that when this event is triggered, they can access the contents of the resource they had asked for (as well as the response code and type).</div>
<div class="p2">
<br /></div>
<div class="p1">
In programming terms, for a component developer, the <b><i>Web.Get</i></b> call block will have to <b><i>create and launch a new thread</i></b> to grab the resource that the user wants from the Internet. Once the resource is retrieved, this new thread will <b><i>communicate back</i></b> to the app by triggering the <b><i>Web.GotText event in the UI thread</i></b>. Let’s see this in code.</div>
<div class="p2">
<br /></div>
<div class="p1">
<b>First part: running a new thread with the request</b></div>
<div class="p1">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"> @SimpleFunction</span></div>
<div class="p1">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"> public void Get() {</span></div>
<div class="p1">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"> [... some config code here ...]</span></div>
<div class="p2">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><br /></span></div>
<div class="p1">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"> AsynchUtil.runAsynchronously(<span class="s1" style="background-color: #93c47d;">new Runnable</span>() {</span></div>
<div class="p1">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"> @Override</span></div>
<div class="p1">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"> public void run() {</span></div>
<div class="p1">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"> try {</span></div>
<div class="p3">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><span class="s2"> </span><span style="background-color: #93c47d;">performRequest</span>(webProps, null, null);</span></div>
<div class="p1">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"> } [... exception handling code here ...]</span></div>
<div class="p1">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"> }</span></div>
<div class="p1">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"> });</span></div>
<div class="p4">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"> }</span></div>
<div class="p1">
<b><br /></b></div>
<div class="p1">
</div>
<div class="p1">
The main thing we want to observe here is that the call to <i>performRequest</i> is done inside a Runnable object, which will be a thread spawning from the UI thread. This is step 1 of our event-driven design. Whatever we need to do in this method, and however long it takes, is not a concern anymore (to a certain extent!) because it will be performed outside of the UI thread.</div>
<div class="p2">
<br /></div>
<div class="p1">
<b>Second part: processing the request and going back to the UI thread</b></div>
<div class="p3">
Lets see now what the <i>performRequest</i> method does, and how it connects back to the UI thread:</div>
<div class="p3">
<br /></div>
<div class="p3">
</div>
<div class="p1">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"> private void performRequest(final CapturedProperties webProps, byte[] </span></div>
<div class="p1">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"> postData, String postFile) throws IOException {</span></div>
<div class="p2">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><br /></span></div>
<div class="p1">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"> // Open the connection.</span></div>
<div class="p3">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><span class="s1"> </span>HttpURLConnection connection = openConnection(webProps);</span></div>
<div class="p1">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"> if (connection != null) {</span></div>
<div class="p1">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"> try {</span></div>
<div class="p1">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"> if (postData != null) {</span></div>
<div class="p3">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><span class="s1"> </span>writePostData(connection, postData);</span></div>
<div class="p1">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"> } [... other code to write to file ...]</span><span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"> </span></div>
<div class="p1">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"> [... some more code to deal with the data; note that this code, and</span></div>
<div class="p1">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"> other actions such as opening a HTTP connection at the top of</span></div>
<div class="p1">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"> this method, can take a long time ...]</span></div>
<div class="p1">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"> // Dispatch the event.</span></div>
<div class="p4">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><span class="s1"> </span><span style="background-color: #93c47d;">activity.runOnUiThread</span>(new Runnable() {</span></div>
<div class="p1">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"> @Override</span></div>
<div class="p1">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"> public void run() {</span></div>
<div class="p1">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"> <span class="s2" style="background-color: #93c47d;">GotText</span>(webProps.urlString, responseCode, responseType, path);</span></div>
<div class="p1">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"> }</span></div>
<div class="p1">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"> });</span></div>
<div class="p1">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"> [... more code to handle files instead of text responses ...]</span></div>
<div class="p1">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"> } finally {</span></div>
<div class="p1">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"> connection.disconnect();</span></div>
<div class="p1">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"> }</span></div>
<div class="p1">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"> }</span></div>
<div class="p5">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"> }</span></div>
<div class="p3">
<br /></div>
<div class="p3">
</div>
<div class="p1">
What is going on here? Well, a HTTP connection is opened against the resource on the web that the user wants to access. Depending on configuration, the user can decide to save the response to a file, or in the code that we can see here, just treat it as text. Once the data is read from the web, this thread’s job is done, and it <b><i>can invoke the user’s event handling block</i></b>, which runs in the UI thread. It will do so by triggering the GotText method inside a Runnable object, but as you can see, it is <b><i>run through the activity.runOnUiThread method</i></b> in order to switch back to the UI thread.</div>
<div class="p1">
Note that operations such as opening a HTTP connection will take a while and will also <b><i>block</i></b> the thread until they are done. That concept of <b><i>blocking the thread</i></b> is exactly what we are trying to avoid in the UI thread, but we don’t mind if this other thread gets blocked for as long as it needs. This is the basis of Asynchronous programming as explained in the previous blog post, and we can take advantage of it to give our users a more pleasant experience while using our apps.</div>
<div class="p2">
<br /></div>
<div class="p3">
Wondering what that <b><i>AsyncUtil.runAsynchronously</i></b> method in the Get function is about? Well, these longer tasks are so frequent in App Inventor that there is some supporting code to accomplish them. The class <a href="https://github.com/mit-cml/appinventor-sources/blob/master/appinventor/components/src/com/google/appinventor/components/runtime/util/AsynchUtil.java"><span class="s1">AsyncUtil.java</span></a> can be used to spawn new threads for the component code. This is the method used in the Web component:</div>
<div class="p3">
<br /></div>
<div class="p3">
</div>
<div class="p1">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"> /**</span></div>
<div class="p1">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"> * Make an asynchronous call in a separate thread.</span></div>
<div class="p1">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"> * @param call a {@link Runnable} to run in the thread.</span></div>
<div class="p1">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"> */</span></div>
<div class="p1">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"> public static void runAsynchronously(final Runnable call) {</span></div>
<div class="p1">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"> Thread thread = <span class="s1" style="background-color: #93c47d;">new Thread</span>(call);</span></div>
<div class="p1">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"> thread.<span class="s1" style="background-color: #93c47d;">start</span>();</span></div>
<div class="p2">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"> }</span></div>
<br />
<div class="p3">
<b id="docs-internal-guid-53e7fe6d-3c32-edf0-b134-e24876626674" style="font-weight: normal;"></b></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<b id="docs-internal-guid-53e7fe6d-3c32-edf0-b134-e24876626674" style="font-weight: normal;"><span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;">It’s very simple code; you pass in a </span><a href="http://docs.oracle.com/javase/7/docs/api/java/lang/Runnable.html" style="text-decoration: none;"><span style="color: #1155cc; font-family: Arial; font-size: 15px; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap;">Runnable</span></a><span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"> object, and the method creates a thread and starts it. This is the basic threading mechanism in Java. For more information have a look at the </span><a href="http://docs.oracle.com/javase/tutorial/essential/concurrency/index.html" style="text-decoration: none;"><span style="color: #1155cc; font-family: Arial; font-size: 15px; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap;">Concurrency tutorial</span></a><span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;">.</span></b></div>
<b id="docs-internal-guid-53e7fe6d-3c32-edf0-b134-e24876626674" style="font-weight: normal;"><br /><span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"></span><br /><span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"></span><span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;">There are many other examples in the </span><a href="http://appinventor.mit.edu/appinventor-sources/" style="text-decoration: none;"><span style="color: #1155cc; font-family: Arial; font-size: 15px; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap;">App Inventor sources</span></a><span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"> showing this kind of event-driven approach to longer operations. When you are creating a component, think that any operation that needs to access resources such as the network or external storage, will need to be designed in this way. You might think that, for instance, if you only read small files from storage, then you will be fine doing it in the UI thread. You might even try it, and test it for a bit, and convince yourself that it works fine, but believe me, it will not cut it in the real world. Think about users with slower and older devices, or slow connections to the Internet, or simply think of a device that, at a particular time, might be busy doing some other operation such as upgrading a different app. You really want to get your design correct and functional for all your users out there!</span></b></div>
</div>
joshttp://www.blogger.com/profile/03322746770159735235noreply@blogger.com4