Pages

Showing posts with label Android. Show all posts
Showing posts with label Android. Show all posts

Sunday 24 March 2013

Application Stats on Android Market

[This post is by Eric Chu, Android Developer Ecosystem. —Dirk Dougherty]

On the Android Market team, it’s been our goal to bring you improved ways of seeing and understanding the installation performance of your published applications. We know that this information is critical in helping you tune your development and marketing efforts. Today I’m pleased to let you know about an important new feature that we’ve added to Android Market called Application Statistics.

Application Statistics is a new type of dashboard in the Market Developer Console that gives you an overview of the installation performance of your apps. It provides charts and tables that summarize each app’s active installation trend over time, as well as its distribution across key dimensions such as Android platform versions, devices, user countries, and user languages. For additional context, the dashboard also shows the comparable aggregate distribution for all app installs from Android Market (numbering in the billions). You could use this data to observe how your app performs relative to the rest of Market or decide what to develop next.

To start with, we’ve seeded the application Statistics dashboards with data going back to December 22, 2010. Going forward, we’ll be updating the data daily.

We encourage you to check out these new dashboards and we hope they’ll give you new and useful insights into your apps’ installation performance. You can access the Statistics dashboards from the main Listings page in the Developer Console.

Watch for more announcements soon. We are continuing to work hard to deliver more reporting features to help you manage your products successfully on Android Market.

Announcing: Apps for Android

Screenshot of WikiNotes for AndroidWe are pleased to announce that a new open source project has been created on Google code hosting called apps-for-android. Our goal is to share some sample applications that demonstrate different aspects of the Android platform.

The first application to be included in the new project is called WikiNotes for Android.

For anyone not familiar with the concept of a wiki, it is a simple way to link up pages of information using WikiWords (words that use CamelCase). For example, in the previous sentence, both WikiWords and CamelCase would become live links in a Wiki, and would take you to pages of information.

WikiNotes for Android is a form of wiki known as a personal wiki. These run on desktops or (in this case) mobile computing devices, and many people like them. They bring a bit more structure to your notes than just a list of subjects. You can choose to link notes or pages up in any manner you like.

This particular implementation uses a regular expression to match WikiWords and turn them into links that fire Intents to go to other notes. Because of the way the links are implemented, the application will also create links out of telephone numbers that take you to the dialer and URLs that start up the browser.

Search by title and content is also implemented, so even if you forget the structure, you can still find that all-important note about where you left your car in the airport car park.

This wiki has a view mode and an edit mode. In view mode, the links become active and allow you to navigate to other notes, or to other activities like dialer and web browser. In edit mode, you see a plain text view that you can edit, and when you confirm the changes it goes back to view mode. There is both a menu entry and keyboard shortcut to switch to edit view, so that you can very quickly make changes. And, if you get lost in the note structure, there is also an option to take you back to the start page.

WikiNotes for Android was written to demonstrate a number of core concepts in Android, including:

  • Multiple Activities in an Application (View, Edit, Search, etc.)
  • Default intent filters for View/Edit/Search based on MIME types
  • Life cycle of Activities
  • Message passing via Bundles in Intents
  • Use of Linkify to add Intent-firing links to text data
  • Using Intents within an application
  • Using Intents to use an Activity within another application
  • Writing a custom ContentProvider that implements search by note title
  • Registration of ReST-like URIs to match titles, and do contents searches
  • SQLite implementations for insert, retrieve, update, delete and search
  • UI layout and creation for multiple activities
  • Menus and keyboard shortcuts

The application remains small in size and features to make it easy to understand. In time, more features will be added to the application to make it more useful, but a sample version with the minimal functionality will always be available for developers new to the Android platform.

If you believe that firing an Intent for every link that is clicked is sub-optimal and will waste resources, please take a look at the running application using DDMS. You will see how efficiently Android re-uses the running Activities and indeed, this is one of the main reasons WikiNotes for Android was written. It demonstrates that using the Android Activities and Intents infrastructure not only makes construction of component-based applications easy, but efficient as well.

There will also be a series of technical articles about the application right here on the Android Developer blog.

And please, keep an eye on the apps-for-android project, as more sample applications will be added to it soon.

Happy wiki-ing.

Backward compatibility for Android applications

Android 1.5 introduced a number of new features that application developers can take advantage of, like virtual input devices and speech recognition. As a developer, you need to be aware of backward compatibility issues on older devices—do you want to allow your application to run on all devices, or just those running newer software? In some cases it will be useful to employ the newer APIs on devices that support them, while continuing to support older devices.

If the use of a new API is integral to the program—perhaps you need to record video—you should add a manifest entry to ensure your app won't be installed on older devices. For example, if you require APIs added in 1.5, you would specify 3 as the minimum SDK version:

  ...  ... 

If you want to add a useful but non-essential feature, such as popping up an on-screen keyboard even when a hardware keyboard is available, you can write your program in a way that allows it to use the newer features without failing on older devices.

Using reflection

Suppose there's a simple new call you want to use, like android.os.Debug.dumpHprofData(String filename). The android.os.Debug class has existed since the first SDK, but the method is new in 1.5. If you try to call it directly, your app will fail to run on older devices.

The simplest way to call the method is through reflection. This requires doing a one-time lookup and caching the result in a Method object. Using the method is a matter of calling Method.invoke and un-boxing the result. Consider the following:

public class Reflect { private static Method mDebug_dumpHprofData; static { initCompatibility(); }; private static void initCompatibility() { try { mDebug_dumpHprofData = Debug.class.getMethod( "dumpHprofData", new Class[] { String.class } ); /* success, this is a newer device */ } catch (NoSuchMethodException nsme) { /* failure, must be older device */ } } private static void dumpHprofData(String fileName) throws IOException { try { mDebug_dumpHprofData.invoke(null, fileName); } catch (InvocationTargetException ite) { /* unpack original exception when possible */ Throwable cause = ite.getCause(); if (cause instanceof IOException) { throw (IOException) cause; } else if (cause instanceof RuntimeException) { throw (RuntimeException) cause; } else if (cause instanceof Error) { throw (Error) cause; } else { /* unexpected checked exception; wrap and re-throw */ throw new RuntimeException(ite); } } catch (IllegalAccessException ie) { System.err.println("unexpected " + ie); } } public void fiddle() { if (mDebug_dumpHprofData != null) { /* feature is supported */ try { dumpHprofData("/sdcard/dump.hprof"); } catch (IOException ie) { System.err.println("dump failed!"); } } else { /* feature not supported, do something else */ System.out.println("dump not supported"); } }}

This uses a static initializer to call initCompatibility, which does the method lookup. If that succeeds, it uses a private method with the same semantics as the original (arguments, return value, checked exceptions) to do the call. The return value (if it had one) and exception are unpacked and returned in a way that mimics the original. The fiddle method demonstrates how the application logic would choose to call the new API or do something different based on the presence of the new method.

For each additional method you want to call, you would add an additional private Method field, field initializer, and call wrapper to the class.

This approach becomes a bit more complex when the method is declared in a previously undefined class. It's also much slower to call Method.invoke() than it is to call the method directly. These issues can be mitigated by using a wrapper class.

Using a wrapper class

The idea is to create a class that wraps all of the new APIs exposed by a new or existing class. Each method in the wrapper class just calls through to the corresponding real method and returns the same result.

If the target class and method exist, you get the same behavior you would get by calling the class directly, with a small amount of overhead from the additional method call. If the target class or method doesn't exist, the initialization of the wrapper class fails, and your application knows that it should avoid using the newer calls.

Suppose this new class were added:

public class NewClass { private static int mDiv = 1; private int mMult; public static void setGlobalDiv(int div) { mDiv = div; } public NewClass(int mult) { mMult = mult; } public int doStuff(int val) { return (val * mMult) / mDiv; }}

We would create a wrapper class for it:

class WrapNewClass { private NewClass mInstance; /* class initialization fails when this throws an exception */ static { try { Class.forName("NewClass"); } catch (Exception ex) { throw new RuntimeException(ex); } } /* calling here forces class initialization */ public static void checkAvailable() {} public static void setGlobalDiv(int div) { NewClass.setGlobalDiv(div); } public WrapNewClass(int mult) { mInstance = new NewClass(mult); } public int doStuff(int val) { return mInstance.doStuff(val); }}

This has one method for each constructor and method in the original, plus a static initializer that tests for the presence of the new class. If the new class isn't available, initialization of WrapNewClass fails, ensuring that the wrapper class can't be used inadvertently. The checkAvailable method is used as a simple way to force class initialization. We use it like this:

public class MyApp { private static boolean mNewClassAvailable; /* establish whether the "new" class is available to us */ static { try { WrapNewClass.checkAvailable(); mNewClassAvailable = true; } catch (Throwable t) { mNewClassAvailable = false; } } public void diddle() { if (mNewClassAvailable) { WrapNewClass.setGlobalDiv(4); WrapNewClass wnc = new WrapNewClass(40); System.out.println("newer API is available - " + wnc.doStuff(10)); } else { System.out.println("newer API not available"); } }}

If the call to checkAvailable succeeds, we know the new class is part of the system. If it fails, we know the class isn't there, and adjust our expectations accordingly. It should be noted that the call to checkAvailable will fail before it even starts if the bytecode verifier decides that it doesn't want to accept a class that has references to a nonexistent class. The way this code is structured, the end result is the same whether the exception comes from the verifier or from the call to Class.forName.

When wrapping an existing class that now has new methods, you only need to put the new methods in the wrapper class. Invoke the old methods directly. The static initializer in WrapNewClass would be augmented to do a one-time check with reflection.

Testing is key

You must test your application on every version of the Android framework that is expected to support it. By definition, the behavior of your application will be different on each. Remember the mantra: if you haven't tried it, it doesn't work.

You can test for backward compatibility by running your application in an emulator from an older SDK, but as of the 1.5 release there's a better way. The SDK allows you to specify "Android Virtual Devices" with different API levels. Once you create the AVDs, you can test your application with old and new versions of the system, perhaps running them side-by-side to see the differences. More information about emulator AVDs can be found in the SDK documentation and from emulator -help-virtual-device.


Learn about Android 1.5 and more at Google I/O. Members of the Android team will be there to give a series of in-depth technical sessions and to field your toughest questions.

Announcing the Android 1.0 SDK, release 1

About this time last year, my colleagues and I were preparing for the first of the "early look" SDK releases. I remember being a little freaked out—November 12 was starting to sound awfully close! But I think I can safely speak for the entire Android team when I say that we were all very excited about that upcoming release. In the year since, we've run and concluded the first Android Developer Challenge, given away $5,000,000, released more SDK builds, and worked with our partners to prepare the first device for users. It's been quite the whirlwind of a year.

In one of those strange cosmic symmetries, here we are a year later, and we're once again very excited about an upcoming release. I'm referring, of course, to the first Android-powered device that our colleagues at T-Mobile have just announced—the T-Mobile G1. We can't wait to see our hard work on store shelves and in the hands of users, but today we're almost as excited because we're announcing the brand-new Android 1.0 SDK, release 1.

Yes, that means we're officially at 1.0. Of course the SDK won't remain static—we'll keep improving the tools by adding features and fixing bugs. But now developers can rely on the APIs in the SDK, and can update their applications to run on Android 1.0-compatible devices. The Android Market beta will also launch with the T-Mobile G1, providing developers an easy and open way to distribute their applications on that and later devices. I've already seen a lot of applications that have me stoked, and I can't wait to see things really come together as developers cross that final mile to prepare their applications for Android 1.0.

So what's next for us? Well, we'll keep working on the SDK, as I said. But we're also working hard with our partners in the Open Handset Alliance on the open-source release, with the aim of making the code available in the fourth quarter. The second Android Developer Challenge is also on the horizon—watch this space for more details. We're also already working on the future of the Android platform, and on more devices. We've updated the Developer Roadmap, and we'll keep updating it as more information becomes available.

It has indeed been quite an exciting road to get to where we are today. The road stretches on ahead though, and we're not slowing down for a moment. I look forward to meeting and working with many of you developers out there—and trying out your apps on my phone!

Happy Coding!

Saturday 23 March 2013

Android SDK Updates

Today we are releasing updates to multiple components of the Android SDK:

  • Android 2.0.1, revision 1
  • Android 1.6, revision 2
  • SDK Tools, revision 4

Android 2.0.1 is a minor update to Android 2.0. This update includes several bug fixes and behavior changes, such as application resource selection based on API level and changes to the value of some Bluetooth-related constants. For more detailed information, please see the Android 2.0.1 release notes.

To differentiate its behavior from Android 2.0, the API level of Android 2.0.1 is 6. All Android 2.0 devices will be updated to 2.0.1 before the end of the year, so developers will no longer need to support Android 2.0 at that time. Of course, developers of applications affected by the behavior changes should start compiling and testing their apps immediately.

We are also providing an update to the Android 1.6 SDK component. Revision 2 includes fixes to the compatibility mode for applications that don't support multiple screen sizes, as well as SDK fixes. Please see the Android 1.6, revision 2 release notes for the full list of changes.

Finally, we are also releasing an update to the SDK Tools, now in revision 4. This is a minor update with mostly bug fixes in the SDK Manager. A new version of the Eclipse plug-in that embeds those fixes is also available. For complete details, please see the SDK Tools, revision 4 and ADT 0.9.5 release notes.

One more thing: you can now follow us on twitter @AndroidDev.

Android Security Update

Recently, there’s been a lot of news coverage of malware in the mobile space. Over on our Mobile blog, Hiroshi Lockheimer, VP of Android engineering, has posted Android and Security. We think most Android developers will find it interesting reading.

Android University

Spring is on the way, and temperatures are rising. We're no exception, and things are starting to heat up over here in Android-land, too.

The Android Developer Challenge deadline is approaching quickly. Wow, that's strange to me. On one hand, we've come so far that the first announcement back on November 12 seems like a prior geologic era, but on the other hand it seems like the Challenge just started! But it's been five months, so it's time to finish your code, polish your UI, and submit your application. Remember to submit by midnight on April 14th, PST (GMT-8).

But after the Challenge, what's next? Well, on the 28th and 29th of May we have Google I/O. This is the biggest Google developer event of the year, and you can bet that the Androids will be there in numbers.

Here are the sessions we've prepared on Android.

  • Android 101: Building an Application
  • Anatomy & Physiology of an Android
  • Dalvik Internals
  • Inside the Android Application Framework
  • Building Great UIs with Android
  • Internationalizing Android Applications
  • Location, Location, Location
  • Mobile Mashups
For more details on these sessions, visit the Google I/O site. Please do, in fact—I'm really excited by some of these because we're going to go into a level of detail that we haven't before. Ever wanted to hear the tech lead on Dalvik talk about Dalvik? Ever wanted an exhaustive review of the i18n/resource system? Then don't miss this event.

Besides the technical sessions, there will be a Fireside Chat with as many members of the Android team as we can rustle up, and an Android section in the demo and coding area. (Personally, I'm looking forward to that the most: it's shaping up to be a code festival of mammoth proportions.) If you need a break from Android, there are also tons of sessions on other developer technologies from Google, too.

We intend this to be the premier developer event for Android, this year. If you only go to one Android event, we humbly suggest that you consider this one. Early-bird registration ends TODAY (April 4th), so be sure to sign up soon.

I'll see you there!

Thursday 21 March 2013

Android NDK r3

The third release of the Android Native Development Kit (NDK) is now available for download from the Android developer site.

It can be used to target devices running Android 1.5 and higher. In addition to a few bug fixes and improvements, this release includes the following new features:

Toolchain improvement

The toolchain binaries have been refreshed for this release with GCC 4.4.0, which should generate slightly more compact and efficient machine code than the previous one (4.2.1).

Note that the GCC 4.4.0 C++ frontend is more pedantic, and may refuse to compile certain rare and invalid template declarations that were accepted by 4.2.1. To alleviate the problem, this NDK still provides the 4.2.1 binaries, which can optionally be used to build your machine code.

OpenGL ES 2.0 support

Applications targeting Android 2.0 (API level 5) or higher can now directly access OpenGL ES 2.0 features. This brings the ability to control graphics rendering through vertex and fragment shader programs, using the GLSL shading language.

A new trivial sample, named "hello-gl2", demonstrates how to render a simple triangle using both shader types.

Name simplification

This NDK release is just called "r3", for "Revision 3", to indicate that it is not limited to a specific Android platform/API level. Some developers thought that the previous release's name (1.6_r1) was confusing and indicated that it could only be used to target Android 1.6, which was not true.

Enjoy!

Android SDK m5-rc14 now available

On behalf of the entire Android team, I'm happy to let you know that an updated version of the Android SDK – we're calling it m5-rc14 – is now available. Today, we're continuing the early look at the Android SDK that we started back in November by providing updates to the Android APIs and the developer tools based, in part, on the great feedback and suggestions developers have been giving us. We're excited about the progress that we've made and look forward to making additional updates in the future as the platform evolves towards production-readiness.

There are a couple of changes in m5-rc14 I'd like to highlight:

  • New user interface - As I mentioned when we introduced the m3 version of the Android SDK, we're continuing to refine the UI that's available for Android. m5-rc14 replaces the previous placeholder with a new UI, but as before, work on it is still in-progress.
  • Layout animations - Developers can now create layout animations for their applications using the capabilities introduced in the android.view.animation package. Check out the LayoutAnimation*.java files in the APIDemos sample code for examples of how this works.
  • Geo-coding - android.location.Geocoder enables developers to forward and reverse geo-code (i.e. translate an address into a coordinate and vice-versa), and also search for businesses.
  • New media codecs - The MediaPlayer class has added support for the OGG Vorbis, MIDI, XMF, iMelody, RTTL/RTX, and OTA audio file formats.
  • Updated Eclipse plug-in - A new version of ADT is available and provides improvements to the Android developer experience. In particular, check out the new Android Manifest editor.

You can find more information about what's changed in a couple of documents that we've published. First is an overview of the changes to the Android APIs in API Changes Overview. If you want a more granular view of what's changed, an API diff between m3-rc37 and m5-rc14 is also available. Finally, Upgrading the SDK provides links to the two previously referenced documents and the release notes, as well as instructions on how to upgrade your development environment.

We still need your help in shaping the platform, so if you find issues with the Android APIs or the developer tools, please let us know through the Android Issue Tracker. If you have general comments or questions, please head on over to the Android groups to get in touch.

We're looking forward to all the applications that developers will create using this new version of the Android SDK. Of course, you can use m5-rc14 or any older version of the SDK for your Android Developers Challenge submission.

Android SDK Tools, Revision 20

[This post is by Xavier Ducrohet, Tech Lead for the Android developer tools]

Along with the preview of the Android 4.1 (Jelly Bean) platform, we launched Android SDK Tools R20 and ADT 20.0.0. Here are a few things that we would like to highlight.
    Application templates: Android ADT supports a new application templates for creating new application, blank activity, master-detail flow, and custom view. These templates support the Android style guide thus making it faster and easier to build beautiful apps. More templates will be added over time.

    Tracer for GLES: With this new tool you can capture the entire sequence of OpenGL calls made by an app into a trace file on the host and replay the captured trace and display the GL state at any point in time.
    Device Monitor: To help you to easily debug your apps, all the Android debugging tools like DDMS, traceview, hierarchyviewer and Tracer for GLES are now built into one single application.
    Systrace: Improving app performance does not have to be a guesswork any more. Systrace for Jelly Bean and above lets you easily optimize your app. You can capture a slice of system activity plus additional information tagged from the Settings > Developer Options > Monitoring: Enable traces or with specific calls added to your application code.

To learn more on the layout editor, XML editing, build system & SDK Manager improvements, please read the ADT 20.0.0 and SDK Tools R20 release notes.

Join us today, June 28th, at the “What’s new in Android developer tools” session for some fun tool demos and a sneak-peak into what’s coming next.

Android SDK update: m5-rc15 released

Earlier today we released an update to the Android SDK – we're calling it m5-rc15. With this update, the SDK now includes all of the incremental changes we've been making to the online documentation since m5-rc14 was released in mid-February. In addition to the latest documentation, we've also fixed a security issue involving handling of image files.

We recommend that you install m5-rc15 at your earliest convenience. The update doesn't change any of the Android APIs or introduce any new ones. Eclipse users don't need to update the ADT plug-in either.

Once you've unzipped the file on your machine, you will want to update things like your PATH variable and, if you're using Eclipse, the SDK location setting for ADT (hint: Preferences > Android).

Android Photostream

I'm pleased to announce that a new open source sample application—called Photostream—has been added to the apps-for-android project. Photostream is a simple photos browser and viewer for Flickr. All you need to use it is a Flickr screen name or user name (the application offers a default user name if you just want to try it.)

This application serves as an illustrative example of several Android features and APIs:

  • Activity aliases
  • Adding custom shortcuts to Home
  • Adding a new wallpaper chooser to the system
  • Custom layouts
  • Custom XML attributes
  • Use of themes
  • Use of styles
  • Use of text colors
  • Use of
  • Use of bitmap and layer drawables from XML
  • Use of HttpClient
  • Proper interaction between background threads and the UI thread
  • Efficient display rotation (using the new onRetainNonConfigurationInstance() API)
  • Animations and layout animations
  • Cropping an image
  • Image manipulation

My favorite feature is the ability to add a new shortcut type in Home, to create a shortcut to any Flickr account. The shortcut shows a custom icon, downloaded from the Flickr user profile:

If you plan on reusing the source code to access Flickr in your own application, you should modify the Flickr.java file to replace the existing API key with your own. The application source code also contains a very handy class called UserTask.java. This class is designed to help you easily write background operations that interact with the UI thread.

Wednesday 20 March 2013

Android Market: a user-driven content distribution system

When we talk to developers, a common topic is the challenge of getting applications in the hands of users. That's why today I'm happy to share early details of Android Market—an open content distribution system that will help end users find, purchase, download and install various types of content on their Android-powered devices. The concept is simple: leverage Google's expertise in infrastructure, search and relevance to connect users with content created by developers like you.

Developers will be able to make their content available on an open service hosted by Google that features a feedback and rating system similar to YouTube. We chose the term "market" rather than "store" because we feel that developers should have an open and unobstructed environment to make their content available. Similar to YouTube, content can debut in the marketplace after only three simple steps: register as a merchant, upload and describe your content and publish it. We also intend to provide developers with a useful dashboard and analytics to help drive their business and ultimately improve their offerings.

I also wanted to share some early details to help with planning your efforts so that you can be ready as our partners release the first Android-powered handsets. Developers can expect the first handsets to be enabled with a beta version of Android Market. Some decisions are still being made, but at a minimum you can expect support for free (unpaid) applications. Soon after launch an update will be provided that supports download of paid content and more features such as versioning, multiple device profile support, analytics, etc. Below are some screenshots that illustrate some of the security features and workflow.

With the addition of a marketplace, the Android ecosystem is becoming even more robust. I am incredibly energized by the support and amazing content I've seen so far. We will share more details as they are available and I look forward to working with many of you in the coming months.

Android Market update: support for priced applications

I'm pleased to announce that Android Market is now accepting priced applications from US and UK developers. Developers from these countries can go to the publisher website at http://market.android.com/publish to upload their application(s) along with end user pricing for the apps. Initially, priced applications will be available to end users in the US starting mid next week. We will add end user support for additional countries in the coming months.

We will also enable developers in Germany, Austria, Netherlands, France, and Spain to offer priced applications later this quarter. By the end of Q1 2009, we will announce support for developers in additional countries. Developers can find more information about priced applications in Android Market at http://market.android.com/support/

Google Checkout will serve as the payment and billing mechanism for Android Market. Developers who do not already have a Google Checkout merchant account can easily sign up for one via the publisher website.

Also, Android Market for free applications will become available to users in Australia starting February 15th Pacific Time and in Singapore in the coming weeks. Developers can now make their applications available in these countries via the publisher website at http://market.android.com/publish.

We look forward to seeing more great applications on Android Market.

Android Market Welcomes Korea!

As of today, Android Market is open for business to application buyers in the Republic of Korea. We hope that this will make the outstanding Android devices now available in that nation even more useful and fun. We welcome the people of Korea, acknowledged everywhere as one of the world's most-wired societies, to the world of Android.

Android Market update: priced applications for US users

Last Friday, we enabled developers to upload priced apps and saw a flurry of activity in the days that followed. Today, it is my pleasure to let you know that we have begun the phased rollout of priced applications to T-Mobile G1 users in the US. Once the service is enabled on their devices, T-Mobile G1 users will be able to see the priced apps immediately without the need to reboot. For more details on this update to Android Market, please see last week's blogpost.

Tuesday 19 March 2013

Android Love at OSCON

Android developers who aren't already going should take a moment to check out the OSCON 2010 schedule, and give serious thought to a trip to Portland in a couple of weeks. OSCON is one of the world's premiere events for those who care about Open Source, and one of my personal favorite conferences, with a powerful community vibe. And this year, the Android drums are sounding.

There are a bunch of mobile and Android-related sessions, both pure and extremely impure; for example, I bet both Steve Jobs and I are dubious about Cross-Compiling Android Applications to the iPhone. There's a full-dress Android for Java Developers tutorial. And (the one I helped cook up) there's the Android Hands-On; last I heard, registration for that is approaching 200 and, since O'Reilly found us a big room, it's not full up; but it will be.

On top of which, there are going to be a herd of Googlers at OSCON, and a sub-herd of Androiders, including Dan Morrill and Justin Mattson and me. This isn't surprising; what does surprise me is that OSCON hasn't previously been an Android love-fest. Because if you're interested in mobile devices and have a hankering for Open Source, Android is for you.

Android Market Problem

Earlier today we had a brief outage in Android Market. For a period of about thirty minutes, some users were unable to find any apps. The problem was detected and corrected, and we believe the user experience is now back to normal. We apologize for the outage.

Android Market Client Update

[This post is by Eric Chu, Android Developer Ecosystem. —Dirk Dougherty]

The Android Market engineering team has been hard at work on improving the Android Market experience for users and developers. Today, I’m pleased to announce a significant update to the Android Market client. Over the next two weeks, we’ll be rolling out a new Android Market client to all devices running Android 1.6 or higher.

This new Market client introduces important features that improve merchandising of applications, streamline the browse-to-purchase experience, and make it easier for developers to distribute their applications.

With a focus on improving discoverability and merchandising, we’ve introduced a new carousel on the home and category screens. Users can quickly flip through the carousel to view promoted applications and immediately go to the download page for the application they want. Developers have been very active in creating great Widgets and Live Wallpapers. To make it easier for users to find their favorites, we’re introducing two new categories for Widgets and Live Wallpapers. Applications that include Widgets and Wallpapers will be automatically added to those new categories. We’ll also be adding more categories for popular applications and games in the weeks ahead. In addition, the app details page now includes Related content, which makes it easier for users to quickly find apps of similar interest.


To streamline the browse-to-purchase experience, users can now access all the information about an application on a single page without the need to navigate across different tabs. We’re also introducing application content rating to provide users with more information about applications they are interested in. Since most users who request a refund do so within minutes of purchase, we will reduce the refund window on Market to 15 minutes. This change will be largely transparent to buyers, but will help developers manage their businesses more effectively.


To make it easier for developers to distribute and manage their products, we will introduce support for device targeting based on screen sizes and densities, as well as on GL texture compression formats. We are also increasing the maximum size for .apk files on Market to 50MB, to better support richer games.

With this release, we aimed to deliver features that are most requested by users and developers. However, we’re not done yet. We plan to continue to rapidly enhance Android Market for both users and developers and make it the best content distribution service for the Android ecosystem.

Please stay tuned as we continue to deliver new capabilities in the coming weeks and months.

Android Layout Tricks #3: Optimize by merging

In the previous installment of Android Layout Tricks, I showed you how to use the tag in XML layout to reuse and share your layout code. I also mentioned the and it's now time to learn how to use it.

The was created for the purpose of optimizing Android layouts by reducing the number of levels in view trees. It's easier to understand the problem this tag solves by looking at an example. The following XML layout declares a layout that shows an image with its title on top of it. The structure is fairly simple; a FrameLayout is used to stack a TextView on top of an ImageView:

   

This layout renders nicely as we expected and nothing seems wrong with this layout:

A FrameLayout is used to overlay a title on top of an image

Things get more interesting when you inspect the result with HierarchyViewer. If you look closely at the resulting tree you will notice that the FrameLayout defined in our XML file (highlighted in blue below) is the sole child of another FrameLayout:

A layout with only one child of same dimensions can be removed

Since our FrameLayout has the same dimension as its parent, by the virtue of using the fill_parent constraints, and does not define any background, extra padding or a gravity, it is totally useless. We only made the UI more complex for no good reason. But how could we get rid of this FrameLayout? After all, XML documents require a root tag and tags in XML layouts always represent view instances.

That's where the tag comes in handy. When the LayoutInflater encounters this tag, it skips it and adds the children to the parent. Confused? Let's rewrite our previous XML layout by replacing the FrameLayout with :

   

With this new version, both the TextView and the ImageView will be added directly to the top-level FrameLayout. The result will be visually the same but the view hierarchy is simpler:

Optimized view hierarchy using the merge tag

Obviously, using works in this case because the parent of an activity's content view is always a FrameLayout. You could not apply this trick if your layout was using a LinearLayout as its root tag for instance. The can be useful in other situations though. For instance, it works perfectly when combined with the tag. You can also use when you create a custom composite view. Let's see how we can use this tag to create a new view called OkCancelBar which simply shows two buttons with customizable labels. You can also download the complete source code of this example. Here is the XML used to display this custom view on top of an image:

   

This new layout produces the following result on a device:

Creating a custom view with the merge tag

The source code of OkCancelBar is very simple because the two buttons are defined in an external XML file, loaded using a LayoutInflate. As you can see in the following snippet, the XML layout R.layout.okcancelbar is inflated with the OkCancelBar as the parent:

public class OkCancelBar extends LinearLayout { public OkCancelBar(Context context, AttributeSet attrs) { super(context, attrs); setOrientation(HORIZONTAL); setGravity(Gravity.CENTER); setWeightSum(1.0f);  LayoutInflater.from(context).inflate(R.layout.okcancelbar, this, true);  TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.OkCancelBar, 0, 0);  String text = array.getString(R.styleable.OkCancelBar_okLabel); if (text == null) text = "Ok"; ((Button) findViewById(R.id.okcancelbar_ok)).setText(text);  text = array.getString(R.styleable.OkCancelBar_cancelLabel); if (text == null) text = "Cancel"; ((Button) findViewById(R.id.okcancelbar_cancel)).setText(text);  array.recycle(); }}

The two buttons are defined in the following XML layout. As you can see, we use the tag to add the two buttons directly to the OkCancelBar. Each button is included from the same external XML layout file to make them easier to maintain; we simply override their id:

   

We have created a flexible and easy to maintain custom view that generates an efficient view hierarchy:

The resulting hierarchy is simple and efficient

The tag is extremely useful and can do wonders in your code. However, it suffers from a couple of limitation:

  • can only be used as the root tag of an XML layout
  • When inflating a layout starting with a , you must specify a parent ViewGroup and you must set attachToRoot to true (see the documentation of the inflate() method)

In the next installment of Android Layout Tricks you will learn about ViewStub, a powerful variation of that can help you further optimize your layouts without sacrificing features.

Download the complete source code of this example.