Friday, October 15, 2010

[Gd] Jason Grigsby’s DOs and DON’Ts of Mobile Strategy

| More

Google Code Blog: Jason Grigsby’s DOs and DON’Ts of Mobile Strategy

Last week Jason Grigsby visited Google as part of our Web Exponents speaker series which highlights innovations in web technology. Jason is a tech leader in mobile web development. In addition to spotting trends in the mobile space, Jason is at the front lines building mobile apps at Cloud Four. His humorous and informative talk includes technology recommendations and insightful examples from the world of mobile. Check out the video of the talk below. You can also download the slides.

Jason’s mobile strategy counterexamples include Chanel (they have an iPhone app but their website is unusable on the iPhone) and the difficulties of finding an Apple Store on the iPhone. His DOs and DON’Ts are:


  1. Know your customers and what devices they use.
  2. Look beyond native apps to mobile web, SMS & MMS.
  3. Apps for your most loyal customers add value.
  4. Consistent experience across devices and offline.
  5. Understand mobile context.


  1. Don’t assume customers have downloaded your app.
  2. Don’t rely on Flash.
  3. Don’t make finding store locations & hours difficult.
  4. Simple to use does not mean dumb.
  5. Don’t forget that the ‘U’ in URL stands for Universal. (He goes on to point out that it really stands for Uniform.)

These all ring true for anyone with experience building for mobile. The hard part is figuring out the right solution for providing the right experience for desktop as well as diverse mobile devices. Jason gives a glimpse into the key features of a solution:

  • integrated image resizing
  • video conversion and resizing
  • separation of content from markup so content can be used in native apps
  • prioritization of content based on context
  • full-featured APIs

The challenge in my opinion is in the steps of breaking out content from markup and determining which content is appropriate for a given device. We need frameworks that better support these ideas, but there’s still a lot of heavy design work on the developer’s shoulders. Jason points to NPR as an example of a large site that has successfully implemented this architecture. Check out Jason’s talk to find out more, and also check out some of the other videos in the Web Exponents playlist.

By Steve Souders, Performance Evangelist

[Gd] [Libraries][Update] jQuery 1.4.3

| More

Google AJAX API Alerts: [Libraries][Update] jQuery 1.4.3

jQuery has been updated to 1.4.3

[Gd] AdWords Downtime: October 16, 10am-2pm PDT

| More

AdWords API Blog: AdWords Downtime: October 16, 10am-2pm PDT

We'll be performing routine system maintenance on Saturday, October 16 from approximately 10:00am to 2:00pm PDT. You won't be able to access AdWords or the API during this time frame, but your ads will continue to run as normal.

- Eric Koleda, AdWords API Team 

[Gd] Traceview War Story

| More

Android Developers Blog: Traceview War Story

I recently took my first serious look at Traceview, and it occurred to me, first, that there are probably a few other Android developers who haven’t used it and, second, that this is an opportunity to lecture sternly on one of my favorite subjects: performance improvement and profiling. This is perhaps a little bit Android-101; If you already know all about Traceview, you can stop here and go back to coding.

Making Apps Fast

Here’s a belief that I think I share with most experienced developers: For any app that is even moderately complex, you’re not smart enough to predict what the slow parts are going to be, because nobody is smart enough to predict where software bottlenecks will turn up.

So the smart way to write a fast app is to build it in the simplest way that could possibly work, avoiding egregiously-stupid thing like order-N-squared algorithms and doing I/O on the Android UI thread. Who knows, it might be fast enough, and then you’re done!

If it isn’t fast enough, don’t guess why. Measure it and find out, using a profiler. Actually I’ve been known to do this, when backed into a corner, using things like System.err.println("Entered at" + System.currentTimeMillis()); Fortunately, Android comes with a reasonably decent profiler, so you don’t have to get ugly like that.

Case Study: LifeSaver 2

I have this little utility in Android Market called LifeSaver 2, the details are on my personal blog. At one point, it reads the SMS and phone-call logs out of the system and persists them in a JSON text file on the SD card. Since this is kind of slow, it shows a nice dynamic progress bar. It occurred to me to wonder why it was kind of slow to write a few hundred records into a text file on a device that, after all, has a gigahertz processor.

Somebody who foolishly disregarded my advice above might assume that the slowdown had to be due to the ContentProvider Cursor machinery reading the system logs, or failing that, the overhead of writing to the SD card. A wiser person would instrument the code and find out. Let’s do that.

Turning On Tracing

I went into and bracketed the code in its run() method like so:

       public void run() {


// ... method body elided


The first call turns tracing on, the argument "lsd" (stands for Life Saver Debug, of course) tells the system to put the trace log in /sdcard/lsd.trace. Remember that doing this means you have to add the WRITE_EXTERNAL_STORAGE permission so you can save the trace info; don‘t forget to remove that before you ship.

[Update:] Android engineer Xavier Ducrohet writes to remind me: “DDMS has a start/stop profiling button in the ‘device view’. Upon clicking stop it launches TraceView with the trace file. This is not as fine grained as putting start/stopMethodTracing in your code but can be quite useful. For VMs earlier than froyo, the permission is required as well (DDMS basically automate getting the trace from the sd card and saving it locally before calling traceview). For Froyo+ VMs, the VM is able to send the trace file through the JDWP connection and the permission is not needed anymore (which is really useful).” Thanks, Xav!

Then you run your app, then you copy the output over to your computer, and fire up Traceview.

540> adb pull /sdcard/lsd.trace
541> traceview lsd

At this point, you will have noticed three things. First, turning tracing on really slows down your app. Second, the tracefile is big; in this case, 8.6M for a run that took like four seconds. Third, that traceview looks pretty cool.

The bars across the top show the app’s threads and how they dealt out the time; since the Nexus One is single-threaded CPU, they have to take turns. Let’s zero in on one 100-msec segment.

The top line is where my app code is running (the red segment is GC happening), the middle line is the UI thread and the bursts of activity are the ProgressBar updating, and I have no idea what the third thread, named HeapWorker, does, but it doesn’t seem a major contributor to the app’s runtime, so let’s ignore it.

The bottom of the screen is where the really interesting data is; it shows which of your methods burned the time, and can be sorted in a bunch of different ways. Let’s zero in on the first two lines.

Translated into English, this tells us that the top-level routine consumed 100% of the time if you include everything it called (well, yeah), but only 0.9% of the time itself. The next line suddenly starts to get real interesting: and whatever it calls are using 65.2% of the app’s time. This is the code that writes the JSON out to the SD card. Right away, we know that apparently the task of pulling the data out of the phone’s ContentProviders doesn’t seem to be very expensive; it’s the output that’s hurting.

Can we conclude that the app is limited by the sluggish write performance of the SD card? Let’s drill down, which is done in the most obvious point-and-click way imaginable.

Ooh, there’s a nasty surprise. Of course, println calls (in effect) toString() on all its arguments. It looks like turning the arguments to strings is taking over half the time, before it even dispatches from println(Object) to println(String).

I’ll skip the step of drilling down into println(String) but it does suggest that yes, there is some slow I/O happening there, to the SD card. But let’s look inside that String.valueOf() call.

There’s your smoking pistol. It turns out that org.json.JSONObject.toString() is what we professional programmers call a, well, this is a family-friendly operation so I won’t go there. You can poke around inside it, but it’s just depressing.

What you can do, however, is sort all the routines by their “Exclusive” times, as in the number of CPU circles burned right there in the routine. Here are all of them that use 1% or more of the total execution time.

There’s a little bit of GC and Android framework View-wrangling stuff in there, but the display is dominated by org.jason and java.lang.StringBuilder code.

The Conclusion

The real conclusion is that in the case of this app, I actually don’t care about the performance. A user runs it a grand total of two times, once on the old phone and once on the new phone, and it’s got lots of eye candy, so I just don’t think there’s a problem.

If I did want to speed this up, it’s obvious what to do. First, either stop using JSON, or find a cheaper way to serialize it. Second, do fewer println() calls; glom the data together in one big buffer and just blast it out with a single I/O call. But, and here’s the key point, if I’d guessed where the bottlenecks were, I’d have been wrong, mostly.

Traceview is a nice tool, and if you don’t already know it, you owe it to yourself to learn it.


[Gd] New App Engine SDK 1.3.8 includes New Admin Tools and Performance Improvements

| More

Google App Engine Blog: New App Engine SDK 1.3.8 includes New Admin Tools and Performance Improvements

Today, we’re releasing version 1.3.8 of the App Engine SDK. Whether you’re a Java or a Python developer, this release includes several exciting new features for improving monitoring, performance, and maintenance tasks.

Instances Console

This release includes a new page in the Admin Console, called the Instances page. This page allows you to view information about all server instances currently in use by your application. This information can be useful in debugging your application and also understanding its performance characteristics. There’s no configuration needed for this feature. Just click the “Instances” link on the left hand navigation of the Admin Console to see Average QPS, latency, and memory for an instance.

Screenshot of the instances page of the Admin Console

Task Queue Improvements

This release also has a couple new Task Queue features: First, the maximum bucket size that you can specify during queue configuration is now 100, up from 50. Second, we’ve added a new "Run Now" button to the Task Queues section of the Admin Console that enables developers to run a task immediately. This can be very helpful for debugging your tasks in production.

Builtins Directives

This release contains a new feature for Python apps: builtin handlers that allow you to quickly and easily enable standard functionality in your application without adding additional code to your codebase. The libraries available today are remote_api, appstats, and the datastore_admin feature (see below). For example, to use the remote_api with your application, simply add the following to your app.yaml file:

- remote_api: on

If you are already using the remote api endpoint your app, you can choose to remove the entry in the handlers section of your app.yaml and use the above directive instead to simplify your app.yaml file.

Support for builtin handlers is not yet available for Java applications, but will be available in an upcoming release.

Delete all (or a part) of your application’s data

Note: this feature is currently only available by default for Python; see the note below for ways to use it with Java application.

Today, we are releasing an experimental addition to the admin console which provides a simple UI for delete all entities, or all entities of a given kind, in your datastore. To enable this functionality, simply enable the following builtin in your app.yaml file:

- datastore_admin: on

Adding these lines to app.yaml enables the “Datastore Admin” page in your app’s Admin Console, where you can see all of the entity types you are able to delete:

Screenshot of the datastore delete builtin UI

Be aware that these deletes are issued by your application (you can read about how the handler works by looking at this code file in the SDK). For this reason, your application will use resources, most significantly CPU, for the deletions you issue which will count towards your application’s daily resource budget.

Datastore delete is currently available only with the Python runtime. Java applications, however, can still take advantage of this feature by creating a non-default Python application version that enables Datastore Admin in the app.yaml. Native support for Java will be included in an upcoming release.

Python Pre-compilation on by Default

Finally, the python pre-compilation feature we announced in 1.3.5 is now turned on for all new python application uploads using the 1.3.8 SDK by default. If you wish to disable this feature, just specify the flag --no-precompilation on the command line when uploading your app.

This release also contains a few more small features and bug fixes. You can read about the full release in our release notes in Python and Java. As always, your feedback in the forums is appreciated (and had a significant influence on this release!).

Posted by the App Engine Team

Wednesday, October 13, 2010

[Gd] Webmaster Tools - Links to your site updated

| More

Official Google Webmaster Central Blog: Webmaster Tools - Links to your site updated

Webmaster Level: All

The "Links to your site" feature in Webmaster Tools is now updated to show you which domains link the most to your site, in addition to other improvements. On the overview page you'll notice that there are three main sections: the domains linking most to your site, the pages on your site with the most links, and a sampling of the anchor text external sites are using when they link to your site.

Who links the most
Clicking the “More >>” link under the “Who links the most” section will take you to a new view that shows a listing of all the domains that link to your site. Each domain in the list can be expanded to display a sample of pages from your site which are linked to by that domain.

The "More >>" link under each specific domain lists all the pages linked to by that domain. At the top of the page there is a total count of links from that domain and a total count of your site's pages linked to from that domain.

Your most linked content
If you drill into the “Your most linked content” view from the overview page, you’ll see a listing of all your site’s most important linked pages. There's also a link count for each page as well as a count of domains linking to that page. Clicking any of the pages listed will expand the view to show you examples of the leading domains linking to that page and the number of links to the given page from each domain listed. The data used for link counts and throughout the "Links to your site" feature is more comprehensive now, including links redirected using 301 or 302 HTTP redirects.

Each page listed in the "All linked pages" view has an associated "More >>" link which displays all the domains linking to that specific page on your site.

Each domain listed leads to a report of all the pages from that domain linking to your specific page.

We hope the updated “Links to your site” feature in Webmaster Tools will help you better understand where the links to your site are coming from and improve your ability to track changes to your site’s link profile. Please post any comments you have about this updated feature or post your questions in the Webmaster Help Forum. We appreciate your feedback since it helps us to continue to improve the functionality of Webmaster Tools.

Posted by Jonathan Simon, Webmaster Trends Analyst

[Gd] Using a dynamic host page for GWT apps

| More

Google Web Toolkit Blog: Using a dynamic host page for GWT apps

A new article on the GWT articles site discusses some of the benefits of hosting a GWT app in a dynamically generated page vs. static HTML.

Using a Dynamic Host Page for Authentication and Initialization


[Gd] Beta Channel Update

| More

Google Chrome Releases: Beta Channel Update

The Beta channel has been updated to 7.0.517.41 for Windows, Mac, Linux and Chrome Frame.

There were only a few minor fixes in this release, specifically around plugin loading and crashes.

You can find more details about additional changes in this release in the SVN revision log.

If you find new issues, please let us know by filing a bug at

Anthony Laforge
Google Chrome

[Gd] First European OpenSocial event in Utrecht, The Netherlands

| More

OpenSocial API Blog: First European OpenSocial event in Utrecht, The Netherlands

The OpenSocial Foundation and SURFnet are excited to announce the OpenSocial Europe Summit and OpenSocial in Education Industry Spotlight event, to be held in Utrecht, the Netherlands, on Monday, Dec. 6 and Tuesday, Dec. 7, 2010.

The event will focus on the use of the OpenSocial, its technologies and implementations, and will have a special concentration on the use of OpenSocial in Research and Education. This two day event is the first OpenSocial Summit held in Europe, and the first to include an industry specific spotlight.

Day one will feature prominent speakers from the OpenSocial community who will present and demonstrate the nuts and bolts of the specification, including what's new in version 1.1, best practices for building social applications, and the emerging use of OpenSocial within the Enterprise. There will also be technical sessions on understanding Apache Shindig, the open source reference framework for OpenSocial. The first day will conclude with a broad outline of where the community is heading with future releases and a call to action to get involved.

The second day is dedicated to the use of OpenSocial in Research and Education. This will consist of both interactive workshops and presentations. Several industry experts from the Research and Educational sector will discuss their experiences using OpenSocial in their solutions. For example, SURFnet will present its project on implementing a new Collaboration Infrastructure and will demonstrate how OpenSocial plays an important role in this infrastructure by it enabling group centric collaboration in an open, platform independent way.

We’ve setup a wiki page where we will be posting the agenda. While we will do our best to accommodate all who wish to attend, please keep in mind that space is limited. Stay tuned to this blog, the OpenSococial Community list, and the wiki for RSVP information and further details.

The OpenSocial Foundation would like to thank SURFnet for their efforts in organizing and hosting this event.

Posted by Mark Weitzel, President, OpenSocial Foundation

SURFnet is the National Research & Education Network (NREN) organization in The Netherlands. SURFnet develops and provides innovative services for education and research in the field of a hybrid network infrastructure, trusted identity and a pioneering collaboration environment. SURFnet provides access to these services to over one million users in higher education and research in The Netherlands. SURFnet is part of SURF, the collaborative organization for higher education institutions and research institutes, which are together working on breakthrough innovations in ICT. More information on SURFNnet and the Collaboration Infrastructure project.

[Gd] Google Apps Marketplace -- Welcoming Developers Around the World

| More

Google Apps Developer Blog: Google Apps Marketplace -- Welcoming Developers Around the World

Great developers are everywhere, and with today’s App Tuesday we’re happy to welcome a new round of apps from around the world. Brightpearl joins us from the United Kingdom, SprinxCRM from the Czech Republic, Producteev's founders hail from France, and Clio calls Canada home. With the addition of these apps to the Google Apps Marketplace, Google Apps customers now have access to over 90 apps from 25 countries outside the United States, including Australia, Germany, India, Russia, Singapore and more.

With our billing API planned for release later this quarter, we get a lot of questions from international developers wondering how the Marketplace payment policy will apply and whether or not their country will be supported. Our policy includes a revenue sharing exemption period which lasts until 3 months after the release of the Marketplace Billing APIs for a country where you are located. At launch, the number of supported countries will be limited, but like the Android Market the set of supported countries will expand in the following months.

Please see our FAQ for more information, and watch this blog or sign up to our email announcement list to be notified of changes.

If you’re an international developer and would like to build an app for the Google Apps Marketplace, Get Started now. Our team will also be traveling the world to the Google Developer Days and DevFests in São Paulo, Buenos Aries, Munich, Prague, and Moscow. If you’re attending those events, please stop by, introduce yourself and tell us about the exciting apps you’re building!

Posted by Steve Bazyl, Google Apps Marketplace Team

Want to weigh in on this topic? Discuss on Buzz


[Gd] Global Developers Integrating with Google Apps

| More

Google Code Blog: Global Developers Integrating with Google Apps

One of the things we enjoy most at Google is working with talented developers around the world, whether Googlers at one of our many global offices or developers using our APIs to build great products. With today’s App Tuesday we’re excited to introduce some new apps to the Google Apps Marketplace with roots outside the United States.

Brightpearl joins us from the United Kingdom
SprinxCRM is from the Czech Republic
Producteev’s founders hail from France
Clio calls Canada home

With the addition of these apps, Google Apps customers now have easy access to apps from 25 countries outside the United States, including Australia, Germany, India, Russia, Singapore and more. While the initial version of the Google Apps Marketplace Billing API will only be available to US sellers, we want all developers to be able to integrate with Google Apps and sell their business-focused web apps on the Apps Marketplace. Because of this, we recently modified our revenue sharing exemption period to last until 3 months after the release of the Marketplace Billing APIs for a country where you are located. So, if you would like to build an app for the Google Apps Marketplace, Get Started now.

Don’t forget our first ever G-Days in Egypt and Jordan are coming up soon, as our our Google Developer Days and Dev Fests in São Paulo, Buenos Aries, Munich, Prague, and Moscow. If you’re attending those events, please stop by and introduce yourself to members of the Google Apps Marketplace team and tell us about the exciting apps you’re building!

By Steve Bazyl, Google Apps Marketplace Team

Tuesday, October 12, 2010

[Gd] Dev Channel Update

| More

Google Chrome Releases: Dev Channel Update

The Chrome Dev channel has been updated to 8.0.552.0 for all platforms. It contains a number of stability and other improvements. More details about the changes are available in the SVN revision log. If you find new issues, please let us know by filing a bug. Want to change to another Chrome release channel? Find out how.

Jason Kersey
Google Chrome

[Gd] This “this” is Your This

| More

Closure Tools Blog: This “this” is Your This

In a past blog post, we talked about how Closure Compiler makes it easier to share common JavaScript by ensuring that everybody declares what variables they own.

Global variable uniqueness is something that we added checks for fairly early on. Some restrictions are less obvious. In this blog post we’ll talk about the this keyword.

Suppose Nathan wants to outsource hot dog eating contests, so that we don’t need an instance of Nathan to run one. To do so, he takes runHotDogContest and unpackHotDogs off the prototype, and makes them into static methods. The code now looks like this:

Nathan.runHotDogContest = function(player, boxes) {
for (var i = 0; i < boxes.length; i++) {

I want to run 2 hot dog contests, so naturally, I write:

var run = Nathan.runHotDogContest;
run(joey, crateA);
run(kobayashi, crateB);

The code fails with an error that unpackHotDogs is not defined on this. The reason is subtle. To the person writing Nathan.runHotDogContest, this and Nathan seem like interchangeable variables. And as long as you’re testing them by invoking them as:

Nathan.runHotDogContest(joey, crateA);
Nathan.runHotDogContest(kobayashi, crateB);

then they will be interchangeable.

In fact, this is a secret argument to the function. It’s much like any other function argument, except that it appears on the left side of the function call instead of on the right side. So Nathan.runHotDogContest(...) passes Nathan as the this argument, and run(...) passes null as the this argument (which JavaScript helpfully coerces to window).

To make Closure Library usable, the library authors and the library users need to agree on what the arguments to a function mean. This includes secret arguments like this. So we’ve agreed that only constructors and prototype methods may use this, and the this argument must be an instanceof the relevant constructor. Closure Compiler enforces this in --warning_level VERBOSE, and will often emit a warning if it sees this used in a dangerous place.

If you’re writing a function that expects an unusual this context, you can explicitly document it with the @this annotation, and the warning will go away.

Good luck with all of this!

Posted by Nick Santos, Software Engineer

[Gd] Discover v201008 - ServicedAccountService

| More

AdWords API Blog: Discover v201008 - ServicedAccountService

The ability to retrieve a list of client accounts and their details is useful when you’re managing a large number of accounts using the AdWords API. This was previously possible only with AccountService in the legacy v13 version of the AdWords API. The v201008 version introduces the ServicedAccountService, which brings similar functionality to the new AdWords API. This blog post discusses the differences between the old AccountService and the new ServicedAccountService.

Retrieving client account hierarchy

In v13, you could retrieve the list of client accounts linked to an MCC using the getClientAccounts or getClientAccountInfos methods of AccountService. In the v201008 version of the AdWords API, you can use the get method of ServicedAccountService to get the same results. The following code shows the service in action.

// Get the ServicedAccountService.
ServicedAccountService servicedAccountService =
(ServicedAccountService) user.GetService(AdWordsService.v201008.

ServicedAccountSelector selector = new ServicedAccountSelector();

try {
ServicedAccountGraph graph = servicedAccountService.get(selector);

if (graph != null && graph.accounts != null) {
// Display the accounts.
Console.WriteLine("There are {0} customers under this account" +
" hierarchy.", graph.accounts.Length);
for (int i = 0; i < graph.accounts.Length; i++) {
Console.WriteLine("{0}) Customer id: {1}\nLogin email: {2}\n" +
"Company name: {3}\nIsMCC: {4}\n", i + 1,
graph.accounts[i].customerId, graph.accounts[i].login,
} catch (Exception ex) {
Console.WriteLine("Failed to retrieve accounts. Exception says \"{0}\"",

ServicedAccountService also allows you to retrieve links that exist between the accounts. To retrieve the links, set the enablePaging field of ServicedAccountSelector to false. The following code shows how to retrieve account links:

selector.enablePaging = false;
selector.serviceTypes = new ServiceType[] { ServiceType.UI_AND_API,
ServiceType.API_ONLY };
if (graph != null && graph.accounts != null) {
// Display the accounts.
// Display the links.
foreach (Link link in graph.links) {
Console.WriteLine("There is a {0} link of type {1} from" +
"{2:###-###-####} to {3:###-###-####}", link.typeOfLink,

An important difference between AccountService.getClientAccounts and ServicedAccountService.get is that getClientAccounts returns only the immediate child accounts, whereas ServicedAccountService.get() returns all of the accounts in the hierarchy. This was harder to do in v13 as you first had to call getClientAccountInfos to find out whether or not a child account is a manager, and then recursively call getClientAccounts to navigate the entire account hierarchy.

To retrieve only the immediate child accounts of your MCC to mimic the behavior of v13’s getClientAccounts method, you can select the relevant accounts as follows:

private Account[] GetClientAccountsForMCC(ServicedAccountGraph graph,
long mccId) {
List retval = new List();
foreach (Link link in graph.links) {
if ( == mccId) {
foreach (Account account in graph.accounts) {
if (account.customerId == {
return retval.ToArray();

Retrieving and updating account information

In v13, you can retrieve and update some fields of a client account using getAccountInfo and updateAccountInfo. This functionality isn’t yet available in v201008, but will be available in a future version of the AdWords API.

Retrieving MCC alerts

In v13, you could retrieve the MCC alerts about your child accounts using getMccAlerts. This functionality is now available through AlertService, another new service introduced in v201008. We will write more about AlertService in a future post.

Please check out this service and share your feedback with us on the forum.

-- Anash P. Oommen, AdWords API Team

[Gd] GWT 2.1 RC1 is now available

| More

Google Web Toolkit Blog: GWT 2.1 RC1 is now available

Building on the three previous milestones, we're happy to announce the first release candidate (RC1) of GWT 2.1. While we're still focused on the overall theme of making it easier to build cloud portable business apps via some help from our friends at VMware and Spring, there are more than a few aspects that make this milestone a RC.

First we've rounded out the list of components and features that will ship with GWT 2.1. One of these components is a new Editor framework that allows you to bind your DTOs to a customizable UI which handles all of necessary grunt work of validating and syncing change sets. Another is the availability of the SafeHTML component and its integration within the cell-based widgets. After all, we've optimized these new widgets by injecting HTML, we better do it in a secure manner.

Along with the new components and features, we've solidified the Activities/Places, RequestFactory, Editor framework, and Cell-based widget APIs. So, if you're looking to start a project with GWT 2.1, you can feel confident that your team won't have to refactor code because we've switched out interfaces between now and the final release.

Also, if you're looking to get started with GWT 2.1 we have an initial draft of the new Developer Guides. These can be found at the links below (the Editor framework Developer Guide is coming soon).

As with previous milestones, there will be an associated Spring Roo RC1 and SpringSource Tool Suite RC1, that will be available in the next few days. Keep your eye on the SpringSource blog, as Christian and Ben are active contributors.

GWT 2.1 RC is available on our Google Code download site and as
version 2.1-SNAPSHOT in the Google
Maven Snapshot Repository
. We’d love to hear your feedback and thoughts on this release, and our GWT Developer Forum would be the best place to post this information.


[Gd] The Five Steps to Future Hardware Happiness

| More

Android Developers Blog: The Five Steps to Future Hardware Happiness

[This post is by Reto Meier AKA @retomeier, who wrote the book on Android App development. —Tim Bray]

Two questions I regularly get asked are “Why isn’t my app visible on the Market on the (insert device name here)?” and “How can I prepare for GoogleTV and Android tablets?” If you care about how broadly your app is available, pay attention now. Seriously. I don’t want to hear anyone telling me they weren’t told. [Seems a little combative? -Ed. Take it up a notch! -RM]

By now you’ve probably heard of Google TV, the Samsung Galaxy Tab, and the Dell Streak. These are only the vanguard — Android is quickly moving to hardware that is increasingly different from the smartphone devices we’re used to. The variations in hardware — including lack of features like GPS, accelerometers, and video cameras — means it’s time for you to think about what hardware your app needs, and what it can function without.

To make life easier every API includes a FEATURE_* constant. To control your app’s availability on the Android Market, you specify the features required for your app to work. I’d like to encourage you to add manifest Feature nodes for every API you use, specifying them as optional, or not, as appropriate using a manifest uses-feature nodes as shown below:

<uses-feature android:name="android.hardware.microphone"

Market won’t be inferring any future API features

My earlier post on future proofing your apps describes a process of feature inferring that used your app’s permissions to help us ensure apps were only visible on the appropriate hardware.

This process has evolved over time. From now on Market won’t be inferring future API features and we have no way to infer some previously available APIs (eg. sensors). As a result you’ll need to specify your mandatory and optional feature requirements — or risk your app either breaking or not being available for some users.

The 5 steps to future hardware happiness

  1. Specify a uses-feature node for every API feature used by your app. This forces you to think about what your app uses, allowing you to:

  2. Decide which features are necessary for your app to be useful and mark those featured with the attribute required=true. This lets Market hide your app from any device that doesn’t support the hardware features your app requires.

    <uses-feature android:name="android.hardware.telephony"

  3. For features that aren’t strictly required, set required=false.

    <uses-feature android:name="android.hardware.bluetooth"

  4. Then go in to your code and find where you have used the optional features. Use the hasSystemFeature method from the PackageManager to determine if the hardware is available and provide alternative paths for your code as appropriate.

    PackageManager pm = getPackageManager();
    boolean hasCompass = pm.hasSystemFeature(PackageManager.FEATURE_SENSOR_COMPASS);

  5. Now you can sleep soundly in the knowledge that no matter what variation in Android compatible hardware comes to market, your app will always (and only) be available on those it supports.

You can find more details on how the Android Market uses filters to determine whether to show your application to a user who is browsing or searching for applications on a given device at the Market Filters page on the Android Developer Site.