Halloween Costume ideas 2015

Digital archives contain as usually understood by professional archivists and historians.

Latest Post
2009 accessibility Aconcagua Administration Adventure Racing Adventure Travel Adventurists Advice Afghanistan Africa Alaska Alberto Contador Aleutian Islands Alex Honnold Alps Amazon Amherst Amherst Destinations Amherst Hikes Andes Android 1.5 Android 1.6 Android 2.0 Android 2.1 Android 2.2 Android 2.3 Android 2.3.3 Android 3.0 Android 3.2 Android 4.0 Android Design Android Developer Challenge Android Developer Phone Android Market Animals Animation and Graphics Annapurna Announcements Antarctic App Components App Resources Apps Archeology Arctic Arctic Ocean Argentina Art Asia Atacama Desert Atlantic Ocean August Australia Authentication Autumn Aviation Backpacking Backyard Nature Badwater Ultra Baffin Island Baltic Sea BASE Jumping Beach Belchertown Belchertown Destinations Belchertown Hikes Berkshires Best Practices Bhutan Blogging Tips Blogs Book Review Boots Boston Botswana Brazil Broad Peak California Camping Canada Canyoneering Carstensz Pyramid Catatan Puspitasari Central America Central Massachusetts Checkpoint Tracker Children Chile China Cho Oyu Cinta Wanita Circumnavigation Clay Climate Change Climbing Clothing Code Day Colorado Colrain Congo River Connecticut Connectivity Conservation Area Contests Cool Stuff Craft Cycling Dashboard Dave Cornthwaite Death Valley Debugging Denali Developer Console Developer Days Developer Labs Developer profiles Dhaulagiri Dinosaurs Discovery Channel Dolomites Earth Day Easter Island Easthampton Ed Viesturs Educational Eiger El Capitan Endurance Sports Environmental Erving Europe Events Everest Expedition Exploration Explorers Club Fair Fairy House Farm Film Festival Finland Fireworks Fish Hatchery Fitz Roy Food Fourth of July France Free Games Gasherbrum Gaya Hidup Wanita Gear General Adventure Gestures Giro d'Italia Gobi Desert Google I/O Google Play Google Play services Goshen GPS Granby Grand Canyon Greater Boston Greenland Grossology Exhibit Guidelines Hadley Hadley 350th Half Dome Hang Gliding Hawaii Health Hikes Under One Mile Hiking Himalaya History Holyoke Honduras Horse How-to Hubungan Hunting Ice Cream IME impossible2Possible Independence Day India Indoor info Info Seminar Input methods Intents Internet Interview io2010 Italy Japan JNI John Muir Trail Jordan July June Jungfrau K2 K7 Kalahari Kangchenjunga Karakoram Kayaking Kilimanjaro Lake Michigan Lance Armstrong Layout Leadville 100 Leverett Lhotse Libraries Lintas Peristiwa Location Location and Sensors London Long Riders Ludlow Maine Makalu Manaslu Maple Massachusetts Matterhorn Media and Camera Mendon Meru Peak Mexico Mini Golf Mississippi River Missouri River Mongolia Monson Mont Blanc Motivasi Mount Elbrus Mount Everest Mount Rainier Mountain Biking Mountain View Mountaineering Movies Mt. Shasta Munich Museums Music Nameless Tower Namibia Nanga Parbat NASA National Geographic Nature Navigation NDK Nepal New Hampshire New Zealand Newburyport North America North Pole Northampton Northfield Norway Novelet Nuptse Nusantara Nutrition Ocean Okavango Delta Olympics Open source OpenGL ES Optimization Oregon Orizaba Outdoor Outdoor Retailer Outside Magazine Pacific Ocean Packs Paddling Pakistan Palmer Panduan SEO Parade Paragliding Patagonia Pelham Peru Petting Zoo Photography Playground Plum Island Poland Pool Pottery Pumpkins Quabbin Reservoir Quality Quick Search Box Rafting Rahasia Wanita Ray Zahab Reggio Emilia Research Resources Review Road Rally Rowing Roz Savage Running Sailing Sample code Sandbox School Science Scuba Diving SDK updates Sensors September Seven Summits Shelburne Falls Shisha Pangma Shutesbury Silk Road Site News Skateboarding skiing Skydiving Slacklining Sleeping Bags Snowboarding Solstice South Africa South America South Deerfield South Georgia South Hadley South Natick South Pacific South Pole Southern Ocean Space Speech Input Springfield Stand Up Paddling Storytime Strawberries Sturbridge Summer Summer Camp Summit Sunderland Survival Sutton Swimming Switzerland Tanzania Technology Tel Aviv Tents Testing Teva Mountain Games Text and Input Text-to-Speech Thrifty Tibet Torres Del Paine Touch Tour d'Afrique Tour de France Tour Divide Tower Trail Running Train Trango Towers TransRockies Travel Trekking Triathlon Turkey Turner's Falls Tutorial Ueli Steck Ultra Running Ultramarathon UMass United States USA Pro Cycling Challenge User Interface Utah Vancouver Vermont Video Wadi Rum Wakhan Wanita dan Bisnis Water Websites Western Massachusetts Westhampton Widgets Wildlife Williamstown Wingsuits Winter Wisconsin Worcester World Championship Wyoming Yemen Yosemite Zoo

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

As part of our ongoing efforts to provide better tools to help you manage your business, we are introducing merchant sales reporting on Android Market. Developers now have convenient access to monthly reports that detail the financial performance of their applications directly from the Android Market Developer Console.

Based on Google Checkout financial data, these reports provide per-transaction details including additional information such as device information, currency of sale, and currency conversion rate. Developers will be able to easily download these reports as a CSV (comma-separated values) files to enable further analysis at their convenience.

Starting today, developers can download merchant sales reports for March 2011 from the Developer Console. Reports for months going back to January 2010 will be available in the coming weeks. Moving forward, sales reports for each month will be available by the 10th day of the following month.

We hope you’ll find these new sales reports useful. As always, please don’t hesitate to give us feedback through Market Help Center.

[This post is by Nick Butcher, an Android engineer who notices small imperfections, and they annoy him. — Tim Bray]

Since the introduction of the Action Bar design pattern, many applications have adopted it as a way to provide easy access to common actions. In Android 3.0 (or Honeycomb to its friends) this pattern has been baked in as the default navigation paradigm and extended to take advantage of the extra real-estate available on tablets. By using the Action Bar in your Honeycomb-targeted apps, you'll give your users a familiar way to interact with your application. Also, your app will be better prepared to scale across the range of Android devices that will be arriving starting in the Honeycomb era.

Just because Action Bars are familiar, doesn’t mean that they have to be identical! The following code samples and accompanying project demonstrate how to style the Action Bar to match your application’s branding. I’ll demonstrate how to take Honeycomb’s Holo.Light theme and customise it to match this blog’s colour scheme.

<style name="Theme.AndroidDevelopers" parent="android:style/Theme.Holo.Light">
…
</style>

Icon

This step is easy; I’ll use the wonderful Android Asset Studio to create an icon in my chosen colour scheme. For extra credit, I’ll use this image as a starting point to create a more branded logo.

Navigation

Next up, the navigation section of the Action Bar operates in three different modes; I’ll tackle each of these in turn.

Standard

The Action Bar’s standard navigation mode simply displays the title of the activity. This doesn’t require any styling... next!

List

To the left, a standard list drop-down; to the right, the effect we want to achieve.

The default styling in list navigation mode has a blue colour scheme. This is evident when touching the collapsed control in both the top bar, and the selection highlight in the expanded list. We can theme this element by overriding android:actionDropDownStyle with a custom style to implement our colour scheme:

<!-- style the list navigation -->
<style name="MyDropDownNav" parent="android:style/Widget.Holo.Light.Spinner.DropDown.ActionBar">
<item name="android:background">@drawable/ad_spinner_background_holo_light</item>
<item name="android:popupBackground">@drawable/ad_menu_dropdown_panel_holo_light</item>
<item name="android:dropDownSelector">@drawable/ad_selectable_background</item>
</style>

The above uses a combination of state list drawables and 9 patch images to style the collapsed spinner, the top bar of the expanded list and sets the highlight colour when picking an item.

Tabs

Here are the before-and-after shots on the tab navigation control:

The tab navigation control uses the standard blue colouring. We can apply a custom style to android:actionBarTabStyle to set our own custom drawable that uses our desired palette:

<!-- style for the tabs -->
<style name="MyActionBarTabStyle" parent="android:style/Widget.Holo.Light.ActionBarView_TabView">
<item name="android:background">@drawable/actionbar_tab_bg</item>
<item name="android:paddingLeft">32dp</item>
<item name="android:paddingRight">32dp</item>
</style>

Actions

Before-and-after on the individual items in the Action Bar:

The individual action items inherit the default blue background when selected. We can customise this behaviour by overriding android:selectableItemBackground and setting a shape drawable with our desired colouring:

<item name="android:selectableItemBackground">@drawable/ad_selectable_background</item>

The overflow menu also needs some attention as when expanded it shows a blue bar at the top of the list. We can override android:popupMenuStyle and set a custom drawable (in fact the very same drawable we previously used for list navigation) for the top of the overflow menu:

<!-- style the overflow menu -->
<style name="MyPopupMenu" parent="android:style/Widget.Holo.Light.ListPopupWindow">
<item name="android:popupBackground">@drawable/ad_menu_dropdown_panel_holo_light</item>
</style>

Selecting items within the overflow menu also show the default selection colour. We can set our customised selection colour by overriding android:dropDownListViewStyle:

<!-- style the items within the overflow menu -->
<style name="MyDropDownListView" parent="android:style/Widget.Holo.ListView.DropDown">
<item name="android:listSelector">@drawable/ad_selectable_background</item>
</style>

These changes gets us most of the way there but it’s attention to detail that makes an app. Check boxes and radio buttons within menu items in the overflow section are still using the default assets which have a blue highlight. Let’s override them to fit in with our theme:

<item name="android:listChoiceIndicatorMultiple">@drawable/ad_btn_check_holo_light</item>
<item name="android:listChoiceIndicatorSingle">@drawable/ad_btn_radio_holo_light</item>

Background

I’ve left the background transparent as inheriting form Holo.Light works well for our desired palette. If you’d like to customise it you easily override the android:background item on the android:actionBarStyle style:

<style name="MyActionBar" parent="android:style/Widget.Holo.Light.ActionBar">
<item name="android:background">@drawable/action_bar_background</item>
</style>

Bringing it all together

Putting all of these components together we can create a custom style:

<style name="Theme.AndroidDevelopers" parent="android:style/Theme.Holo.Light">
<item name="android:selectableItemBackground">@drawable/ad_selectable_background</item>
<item name="android:popupMenuStyle">@style/MyPopupMenu</item>
<item name="android:dropDownListViewStyle">@style/MyDropDownListView</item>
<item name="android:actionBarTabStyle">@style/MyActionBarTabStyle</item>
<item name="android:actionDropDownStyle">@style/MyDropDownNav</item>
<item name="android:listChoiceIndicatorMultiple">@drawable/ad_btn_check_holo_light</item>
<item name="android:listChoiceIndicatorSingle">@drawable/ad_btn_radio_holo_light</item>
</style>

We can then apply this style to either an individual activity or to the entire application:


<activity android:name=".MainActivity"
android:label="@string/app_name"
android:theme="@style/Theme.AndroidDevelopers"
android:logo="@drawable/ad_logo">

Note that some of the system styles that we have overridden in this example will affect much more than the Action Bar. For example overriding android:selectableItemBackground will effect many widgets which support a selectable state. This is useful for styling your entire application but be sure to test that your customisations are applied consistently throughout.

Familiar but styled

Customising the action bar is a great way to extend your application’s branding to the standard control components. With this power, as they say, comes great responsibility. When customising the user interface you must take great care to ensure that your application remains legible and navigable. In particular, watch out for highlight colours which contrast poorly with text and provide drawables for all relevant states. Explore this demo application which exercises the functionality offered by the Action Bar and demonstrates how to theme it.

[This post is by Bridgette Sexton, an innovation advocate for the African tech community. — Tim Bray]

En Français.

In the past year alone, we have met with over 10,000 developers and techies across Sub Saharan Africa. We are continually impressed by the ingenuity and enthusiasm of this community in solving real problems with technology. From applications that crowd-source traffic info to mobile registration of local businesses, handheld devices have taken center stage for consumers and developers in Africa. With a number of countries in the region hovering around 80-90% mobile penetration, mobile is the screen size for the web and the communication experience.

Correspondingly, at every Google event in Africa, Android is the hottest topic; we know why. Every day over 300,000 Android devices are activated globally! A growing number of these mobile devices are powering on for the first time in emerging markets like those in Africa. As Android users multiply, so does the appeal to for developers of building apps on this free open-source platform.

An increasing number of users are searching for 'Android' on Google in Sub-Saharan Africa

For all these reasons and more, we are proud to be launching the Android Developer Challenge for Sub-Saharan Africa!

The Android Developer Challenge is designed to encourage the creation of cool and innovative Android mobile apps built by developers in Sub-Saharan Africa. Invent apps that delight users and you stand a chance to win an Android phone and $25,000 USD. To get started, choose from one of three defined eligible categories (see below), build an Android app in a team or by yourself, and submit it via the competition website by July 1st. The winning app will be announced on September 12th at G-Kenya. Get more details as well as Terms and Conditions on our site.

Categories for Entry:

  • Entertainment / Media / Games

  • Social Networking / Communication

  • Productivity / Tools / Lifestyle

(See Terms & Conditions for more details!)

To launch this competition, we have teamed up with Google Technology User Groups (GTUGs) across Africa to host Android Developer Challenge events. Check out our website for Android gatherings near you, and get coding!


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

Since last year, we’ve been working to bring the convenience of Direct Carrier Billing to more Android Market users on more carrier networks. Building on the launches to T-Mobile US and AT&T users in 2010, we’ve recently launched Direct Carrier Billing to users on three popular networks in Japan -- SoftBank, KDDI, and NTT DOCOMO.

The momentum continues and today we’re excited to announce that Direct Carrier Billing is now available on Sprint. We've begun a phased roll-out of the service that will reach all users in the next few days. When complete, Android users on the Sprint network will be able to charge their Android Market purchases to their Sprint mobile bill with only a few clicks.

We believe that Direct Carrier Billing is a key payment option because it lets users purchase and pay for apps more easily. It’s also important because it offers a convenient way to buy in regions where credit cards are less common.

We are continuing to partner with more carriers around the world to offer carrier billing options to their subscribers. Watch for announcements of new payment options coming in the months ahead.

[This post is by Andy Rubin, VP of Engineering —Tim Bray]

Recently, there’s been a lot of misinformation in the press about Android and Google’s role in supporting the ecosystem. I’m writing in the spirit of transparency and in an attempt to set the record straight. The Android community has grown tremendously since the launch of the first Android device in October 2008, but throughout we’ve remained committed to fostering the development of an open platform for the mobile industry and beyond.

We don’t believe in a “one size fits all” solution. The Android platform has already spurred the development of hundreds of different types of devices – many of which were not originally contemplated when the platform was first created. What amazes me is that even though the quantity and breadth of Android products being built has grown tremendously, it’s clear that quality and consistency continue to be top priorities. Miraculously, we are seeing the platform take on new use cases, features and form factors as it’s being introduced in new categories and regions while still remaining consistent and compatible for third party applications.

As always, device makers are free to modify Android to customize any range of features for Android devices. This enables device makers to support the unique and differentiating functionality of their products. If someone wishes to market a device as Android-compatible or include Google applications on the device, we do require the device to conform with some basic compatibility requirements. (After all, it would not be realistic to expect Google applications – or any applications for that matter – to operate flawlessly across incompatible devices). Our “anti-fragmentation” program has been in place since Android 1.0 and remains a priority for us to provide a great user experience for consumers and a consistent platform for developers. In fact, all of the founding members of the Open Handset Alliance agreed not to fragment Android when we first announced it in 2007. Our approach remains unchanged: there are no lock-downs or restrictions against customizing UIs. There are not, and never have been, any efforts to standardize the platform on any single chipset architecture.

Finally, we continue to be an open source platform and will continue releasing source code when it is ready. As I write this the Android team is still hard at work to bring all the new Honeycomb features to phones. As soon as this work is completed, we’ll publish the code. This temporary delay does not represent a change in strategy. We remain firmly committed to providing Android as an open source platform across many device types.

The volume and variety of Android devices in the market continues to exceed even our most optimistic expectations. We will continue to work toward an open and healthy ecosystem because we truly believe this is best for the industry and best for consumers.

When Google I/O sold out so fast, were kicking around ideas for how to get some of our ticket reserve into the hands of our favorite people: Dedicated developers. Someone floated the idea of a contest, so we had to pull one together double-quick. You can read the questions and first-round answers here.

We thought you would enjoy some statistics, mostly rounded-off:

  • 2,800 people visited the contest page.

  • 360 people tried answering the questions.

  • 1 person got all six right.

  • 200 people did well enough to get into Round 2.

  • 70 people submitted apps.

  • 38 of the apps worked well enough to be worth considering.

  • 10 apps (exactly) got a “Nice” rating from the first-cut reviewer.

While we’re doing numbers, let’s investigate which of the Round-1 questions were hard. In decreasing order of difficulty, identified by correct answer, we find: Dalvik (97.5% correct), 160 (96%), Looper (58.5%), LLVM (57%), fyiWillBeAdvancedByHostKThx (43%), and PhoneNumberFormattingTextWatcher (19.5%).

So, our thanks to the people who put in the work, and a particular tip of the hat to the deranged hackers er I mean creative developers who built three particularly-outstanding apps:

First, to Kris Jurgowski, who pulled an all-nighter and wrote a nifty little app... on a Motorola CLIQ running Android 1.5! Next, to Heliodor Jalba, whose app had some gravity-warping extras and was less than 11K in size. And finally, to Charles Vaughn, whose app included a hilarious “Party Mode” that brought a smile to everyone’s face.

[The contents of this post grew out of an internal discussion featuring many of the usual suspects who’ve been authors in this space. — Tim Bray]

In the Android group, from time to time we hear complaints from developers about problems they’re having coming up with reliable, stable, unique device identifiers. This worries us, because we think that tracking such identifiers isn’t a good idea, and that there are better ways to achieve developers’ goals.

Tracking Installations



It is very common, and perfectly reasonable, for a developer to want to track individual installations of their apps. It sounds plausible just to call TelephonyManager.getDeviceId() and use that value to identify the installation. There are problems with this
: First, it doesn’t work reliably (see below). Second, when it does work, that value survives device wipes (“Factory resets”) and thus you could end up making a nasty mistake when one of your customers wipes their device and passes it on to another person.

To track installations, you could for example use a UUID as an identifier, and simply create a new one the first time an app runs after installation. Here is a sketch of a class named “Installation” with one static method Installation.id(Context context). You could imagine writing more installation-specific data into the INSTALLATION file.

public class Installation {
private static String sID = null;
private static final String INSTALLATION = "INSTALLATION";

public synchronized static String id(Context context) {
if (sID == null) {
File installation = new File(context.getFilesDir(), INSTALLATION);
try {
if (!installation.exists())
writeInstallationFile(installation);
sID = readInstallationFile(installation);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
return sID;
}

private static String readInstallationFile(File installation) throws IOException {
RandomAccessFile f = new RandomAccessFile(installation, "r");
byte[] bytes = new byte[(int) f.length()];
f.readFully(bytes);
f.close();
return new String(bytes);
}

private static void writeInstallationFile(File installation) throws IOException {
FileOutputStream out = new FileOutputStream(installation);
String id = UUID.randomUUID().toString();
out.write(id.getBytes());
out.close();
}
}

Identifying Devices

Suppose you feel that for the needs of your application, you need an actual hardware device identifier. This turns out to be a tricky problem.

In the past, when every Android device was a phone, things were simpler: TelephonyManager.getDeviceId() is required to return (depending on the network technology) the IMEI, MEID, or ESN of the phone, which is unique to that piece of hardware.

However, there are problems with this approach:

  • Non-phones: Wifi-only devices or music players that don’t have telephony hardware just don’t have this kind of unique identifier.


  • Persistence: On devices which do have this, it persists across device data wipes and factory resets. It’s not clear at all if, in this situation, your app should regard this as the same device.


  • Privilege:It requires READ_PHONE_STATE permission, which is irritating if you don’t otherwise use or need telephony.


  • Bugs: We have seen a few instances of production phones for which the implementation is buggy and returns garbage, for example zeros or asterisks.


Mac Address

It may be possible to retrieve a Mac address from a device’s WiFi or Bluetooth hardware. We do not recommend using this as a unique identifier. To start with, not all devices have WiFi. Also, if the WiFi is not turned on, the hardware may not report the Mac address.

Serial Number

Since Android 2.3 (“Gingerbread”) this is available via android.os.Build.SERIAL. Devices without telephony are required to report a unique device ID here; some phones may do so also.

ANDROID_ID

More specifically, Settings.Secure.ANDROID_ID. This is a 64-bit quantity that is generated and stored when the device first boots. It is reset when the device is wiped.

ANDROID_ID seems a good choice for a unique device identifier. There are downsides: First, it is not 100% reliable on releases of Android prior to 2.2 (“Froyo”). Also, there has been at least one widely-observed bug in a popular handset from a major manufacturer, where every instance has the same ANDROID_ID.

Conclusion

For the vast majority of applications, the requirement is to identify a particular installation, not a physical device. Fortunately, doing so is straightforward.

There are many good reasons for avoiding the attempt to identify a particular device. For those who want to try, the best approach is probably the use of ANDROID_ID on anything reasonably modern, with some fallback heuristics for legacy devices.

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

Today, we're pleased to announce the launch of Android Market In-app Billing to developers and users. As an Android developer, you will now be able to publish apps that use In-app Billing and your users can make purchases from within your apps.

In-app Billing gives you more ways to monetize your apps with try-and-buy, virtual goods, upgrades, and other billing models. If you aren’t yet familiar with In-app Billing, we encourage you to learn more about it.

Several apps launching today are already using the service, including Tap Tap Revenge by Disney Mobile; Comics by ComiXology; Gun Bros, Deer Hunter Challenge HD, and WSOP3 by Glu Mobile; and Dungeon Defenders: FW Deluxe by Trendy Entertainment.

To try In-app Billing in your apps, start with the detailed documentation and complete sample app provided, which show how to implement the service in your app, set up in-app product lists in Android Market, and test your implementation. Also, it’s absolutely essential that you review the security guidelines to make sure your billing implementation is secure.

We look forward to seeing how you’ll use this new service in your apps!

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

Back in January we announced our plan to introduce Android Market In-app Billing this quarter. We're pleased to let you know that we will be launching In-app Billing next week.

In preparation for the launch, we are opening up Android Market for upload and end-to-end testing of your apps that use In-app Billing. You can now upload your apps to the Developer Console, create a catalog of in-app products, and set prices for them. You can then set up accounts to test in-app purchases. During these test transactions, the In-app Billing service interacts with your app exactly as it will for actual users and live transactions.

Note that although you can upload apps during this test development phase, you won’t be able to actually publish the apps to users until the full launch of the service next week.


To get you started, we’ve updated the developer documentation with information about how to set up product lists and test your in-app products. Also, it is absolutely essential that you review the security guidelines to make sure your billing implementation is secure.

We encourage you start uploading and testing your apps right away.

[This post is by Patrick Dubroy, an Android engineer who writes about programming, usability, and interaction on his personal blog. — Tim Bray]

The Dalvik runtime may be garbage-collected, but that doesn't mean you can ignore memory management. You should be especially mindful of memory usage on mobile devices, where memory is more constrained. In this article, we're going to take a look at some of the memory profiling tools in the Android SDK that can help you trim your application's memory usage.

Some memory usage problems are obvious. For example, if your app leaks memory every time the user touches the screen, it will probably trigger an OutOfMemoryError eventually and crash your app. Other problems are more subtle, and may just degrade the performance of both your app (as garbage collections are more frequent and take longer) and the entire system.

Tools of the trade

The Android SDK provides two main ways of profiling the memory usage of an app: the Allocation Tracker tab in DDMS, and heap dumps. The Allocation Tracker is useful when you want to get a sense of what kinds of allocation are happening over a given time period, but it doesn't give you any information about the overall state of your application's heap. For more information about the Allocation Tracker, see the article on Tracking Memory Allocations. The rest of this article will focus on heap dumps, which are a more powerful memory analysis tool.

A heap dump is a snapshot of an application's heap, which is stored in a binary format called HPROF. Dalvik uses a format that is similar, but not identical, to the HPROF tool in Java. There are a few ways to generate a heap dump of a running Android app. One way is to use the Dump HPROF file button in DDMS. If you need to be more precise about when the dump is created, you can also create a heap dump programmatically by using the android.os.Debug.dumpHprofData() function.

To analyze a heap dump, you can use a standard tool like jhat or the Eclipse Memory Analyzer (MAT). However, first you'll need to convert the .hprof file from the Dalvik format to the J2SE HPROF format. You can do this using the hprof-conv tool provided in the Android SDK. For example:

hprof-conv dump.hprof converted-dump.hprof

Example: Debugging a memory leak

In the Dalvik runtime, the programmer doesn't explicitly allocate and free memory, so you can't really leak memory like you can in languages like C and C++. A "memory leak" in your code is when you keep a reference to an object that is no longer needed. Sometimes a single reference can prevent a large set of objects from being garbage collected.

Let's walk through an example using the Honeycomb Gallery sample app from the Android SDK. It's a simple photo gallery application that demonstrates how to use some of the new Honeycomb APIs. (To build and download the sample code, see the instructions.) We're going to deliberately add a memory leak to this app in order to demonstrate how it could be debugged.

Imagine that we want to modify this app to pull images from the network. In order to make it more responsive, we might decide to implement a cache which holds recently-viewed images. We can do that by making a few small changes to ContentFragment.java. At the top of the class, let's add a new static variable:

private static HashMap<String,Bitmap> sBitmapCache = new HashMap<String,Bitmap>();

This is where we'll cache the Bitmaps that we load. Now we can change the updateContentAndRecycleBitmap() method to check the cache before loading, and to add Bitmaps to the cache after they're loaded.

void updateContentAndRecycleBitmap(int category, int position) {
if (mCurrentActionMode != null) {
mCurrentActionMode.finish();
}

// Get the bitmap that needs to be drawn and update the ImageView.

// Check if the Bitmap is already in the cache
String bitmapId = "" + category + "." + position;
mBitmap = sBitmapCache.get(bitmapId);

if (mBitmap == null) {
// It's not in the cache, so load the Bitmap and add it to the cache.
// DANGER! We add items to this cache without ever removing any.
mBitmap = Directory.getCategory(category).getEntry(position)
.getBitmap(getResources());
sBitmapCache.put(bitmapId, mBitmap);
}
((ImageView) getView().findViewById(R.id.image)).setImageBitmap(mBitmap);
}

I've deliberately introduced a memory leak here: we add Bitmaps to the cache without ever removing them. In a real app, we'd probably want to limit the size of the cache in some way.

Examining heap usage in DDMS

The Dalvik Debug Monitor Server (DDMS) is one of the primary Android debugging tools. DDMS is part of the ADT Eclipse plug-in, and a standalone version can also be found in the tools/ directory of the Android SDK. For more information on DDMS, see Using DDMS.

Let's use DDMS to examine the heap usage of this app. You can start up DDMS in one of two ways:

  • from Eclipse: click Window > Open Perspective > Other... > DDMS
  • or from the command line: run ddms (or ./ddms on Mac/Linux) in the tools/ directory

Select the process com.example.android.hcgallery in the left pane, and then click the Show heap updates button in the toolbar. Then, switch to the VM Heap tab in DDMS. It shows some basic stats about our heap memory usage, updated after every GC. To see the first update, click the Cause GC button.

We can see that our live set (the Allocated column) is a little over 8MB. Now flip through the photos, and watch that number go up. Since there are only 13 photos in this app, the amount of memory we leak is bounded. In some ways, this is the worst kind of leak to have, because we never get an OutOfMemoryError indicating that we are leaking.

Creating a heap dump

Let's use a heap dump to track down the problem. Click the Dump HPROF file button in the DDMS toolbar, choose where you want to save the file, and then run hprof-conv on it. In this example, I'll be using the standalone version of MAT (version 1.0.1), available from the MAT download site.

If you're running ADT (which includes a plug-in version of DDMS) and have MAT installed in Eclipse as well, clicking the “dump HPROF” button will automatically do the conversion (using hprof-conv) and open the converted hprof file into Eclipse (which will be opened by MAT).

Analyzing heap dumps using MAT

Start up MAT and load the converted HPROF file we just created. MAT is a powerful tool, and it's beyond the scope of this article to explain all it's features, so I'm just going to show you one way you can use it to detect a leak: the Histogram view. The Histogram view shows a list of classes sortable by the number of instances, the shallow heap (total amount of memory used by all instances), or the retained heap (total amount of memory kept alive by all instances, including other objects that they have references to).

If we sort by shallow heap, we can see that instances of byte[] are at the top. As of Android 3.0 (Honeycomb), the pixel data for Bitmap objects is stored in byte arrays (previously it was not stored in the Dalvik heap), and based on the size of these objects, it's a safe bet that they are the backing memory for our leaked bitmaps.

Right-click on the byte[] class and select List Objects > with incoming references. This produces a list of all byte arrays in the heap, which we can sort based on Shallow Heap usage.

Pick one of the big objects, and drill down on it. This will show you the path from the root set to the object -- the chain of references that keeps this object alive. Lo and behold, there's our bitmap cache!

MAT can't tell us for sure that this is a leak, because it doesn't know whether these objects are needed or not -- only the programmer can do that. In this case, the cache is using a large amount of memory relative to the rest of the application, so we might consider limiting the size of the cache.

Comparing heap dumps with MAT

When debugging memory leaks, sometimes it's useful to compare the heap state at two different points in time. To do this, you'll need to create two separate HPROF files (don't forget to convert them using hprof-conv).

Here's how you can compare two heap dumps in MAT (it's a little complicated):

  1. Open the first HPROF file (using File > Open Heap Dump).
  2. Open the Histogram view.
  3. In the Navigation History view (use Window > Navigation History if it's not visible), right click on histogram and select Add to Compare Basket.
  4. Open the second HPROF file and repeat steps 2 and 3.
  5. Switch to the Compare Basket view, and click Compare the Results (the red "!" icon in the top right corner of the view).

Conclusion

In this article, I've shown how the Allocation Tracker and heap dumps can give you get a better sense of your application's memory usage. I also showed how The Eclipse Memory Analyzer (MAT) can help you track down memory leaks in your app. MAT is a powerful tool, and I've only scratched the surface of what you can do with it. If you'd like to learn more, I recommend reading some of these articles:

[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.

MKRdezign

Contact Form

Name

Email *

Message *

Powered by Blogger.
Javascript DisablePlease Enable Javascript To See All Widget