This article was written and submitted by an external developer. The Google Desktop Team thanks Teodor Filimon for his time and expertise.
"Something cannot emerge from nothing." - Frank Herbert
More and more gadgets, especially in the Web 2.0 era, have to communicate with the online world to provide fresh data and interactivity between users. Unlike a web-based gadget, a Desktop gadget also has to know what to do when the user is offline.
First of all, we have to realize that gadgets can do a lot of things while online, such as fetching news, feeds or images and interacting with other users of the same gadget. There are several ways to see if the computer is online or offline:
framework.system.network.online can be used for general purposes.
function isNetworkOnline() {
return framework.system.network.online;
}
If you're using the Google Talk API, it might be a good idea to keep an eye on the googleTalk.talk_status property. It can return three values:
gddTalkStatusNotRunninggddTalkStatusDisconnectedgddTalkStatusConnectedThese values are actually represented by the integers 0, 1 and 2. I used this property in Cupid's gadget for offline detection:
function refresh(){
//...
//check if Google Talk is not running or not installed
if (googleTalk.talk_status==gddTalkStatusNotRunning) {
NoFriendsOnline();
ShowMessage(1);
return 0;
}
//check if Google Talk is running but not connected
if (googleTalk.talk_status==gddTalkStatusDisconnected) {
NoFriendsOnline();
ShowMessage(2);
return 0;
}
//notice how the function will stop when a return will be executed
//therefore it will get here only when Google Talk is connected
Bookmark.visible=true;
ShowMessage(0);
}
More about offline and online detection can be found in this article.
Ultimately the user should be able to see the current connection status. However, the changes in the interface should be suggestive as you can see in Figure 1. The most important UI element (big red heart) is replaced by an appropriate status message.

Notice how the gadget doesn't pop up an intrusive error dialog or output a message like "Error 235: Connection not found". :) Instead it guides the user to make the most out of the gadget. You can go further by applying different modes to the interface, as described in this article. For example, when the user goes offline, the gadget could shrink down and give up the visual space required by the online functionality.
So you've made a gadget that gathers the latest news and
posts from a feed or just parses a big XML file. It needs to fetch the items periodically to keep the data fresh. But what if there is no Internet connection the next time the gadget is loaded? The best solution is storing the data using options. If the array consists of JavaScript objects, you can use JSON to serialize the objects to a string and deserialize the string to objects.
A good example of persisting data to options is the Tabbed ToDo List gadget. Within the source, you can see exactly what functions to call for the conversions to and from JSON strings. The tasks, tabs, and checkbox values are continually persisted and recreated with the help of JSON.
function change(){
//memorizes the new todolist
options("todoList")=todoList.toJSONString();
options("tabs")=tabs.toJSONString();
options("values")=values.toJSONString();
//todoList, tabs and values are all arrays
}
function show(){
//shows the remembered todo list
todoList=options("todoList").parseJSON();
values=options("values").parseJSON();
tabs=options("tabs").parseJSON();
//...
}
These methods are defined in a .js script file downloadable from the JSON site. That script has to be included in your main.xml file just as you would include main.js.
We've seen how to add offline robustness to a gadget across sessions, but we should also be mindful of CPU and memory usage.
A common, potentially expensive operation is sorting an array. You might want to order items by value and interest to the user, such as unchecked tasks in a to-do list or unread items in a news feed. In such cases don't forget about the Ranking API, which sorts items based on various criteria like number of clicks, publishing time, etc.
The most expensive activity in terms of CPU is one that repeats periodically. The setInterval and setTimeout functions are widely used, but should be used carefully. Infinite call cycles should be avoided and timers should be destroyed when they're not used.
function myFunction(){
alert("Alert");
}
token=setInterval("myFunction()",10000);
//this timer will call myFunction once every 10 seconds
//when the timer isn't needed it should be deleted
//we can do this using the token returned by setInterval
clearInterval(token);
//you can also delete a timeout, using clearTimeout
You can find out more about these functions, including some that can be particularly helpful for animations, by checking out the documentation for the view object.
Similar safeguards should be used to optimize memory usage as well.
Declaring variables locally is usually better then globally.
Objects should also be deleted or set to null if they aren't used anymore.
For example, audioclips should be set to null once they've been played and are no longer needed.
To create the best application possible, it's important to be aware of these workarounds, safeguards, and best practices and to apply them appropriately when needed.
Many gadgets, everyone!
I'm a natural born programmer. My first contact with a techno-gadget was Star Trek (remember those cool sensors?). I used to fill up a whole room with drawings of them when I was only 3 years old. Generally, I find a lot of inspiration for intuitive interfaces in things with "star" in their names (like Star Wars, Stargate,... :-) . I like the border between interface and function—it's the essence of a program, I think. Anyway, I'm a software engineering student now, and you can learn more about me and what I'm thinking and doing at my website or blog. My most popular gadgets are DigiWatch and TV Set.
This work is licensed under a
Creative Commons Attribution-Noncommercial-No Derivative Works 3.0 United States License.