28
Managing Android Fragmentation Carter Jernigan two forty four a.m. LLC

Presentation--MoMo Managing Android

  • Upload
    others

  • View
    3

  • Download
    0

Embed Size (px)

Citation preview

Managing Android Fragmentation

Carter Jernigantwo forty four a.m. LLC

#1 Android 2.1+ only

http://developer.android.com/resources/dashboard/platform-versions.html

Only 1.6% of all Android users are running pre 2.0 versions of Android. Not only is the Android 1.0 market small, but all the growth is under Android 2.3 or later. So why divert significant development effort to support less than 2% of your user base?

public class AndroidTestActivity extends Activity{ /** Called when the activity is first created. */ @Override public void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main);

// Only for Gingerbread or later if (Integer.parseInt(android.os.Build.VERSION.SDK) > 9) { try { final Class<?> strictModeClass = Class.forName("android.os.StrictMode"); //$NON-NLS-1$ final Method enableDefaultsMethod = strictModeClass.getMethod("enableDefaults"); //$NON-NLS-1$ enableDefaultsMethod.invoke(strictModeClass); } catch (final ClassNotFoundException e) { throw new RuntimeException(e); } catch (final SecurityException e) { throw new RuntimeException(e); } catch (final NoSuchMethodException e) { throw new RuntimeException(e); } catch (final IllegalArgumentException e) { throw new RuntimeException(e); } catch (final IllegalAccessException e) { throw new RuntimeException(e); } catch (final InvocationTargetException e) { throw new RuntimeException(e); } } }}

The Dalvik virtual machine changed significantly between Android 1.6 and Android 2.0 with respect to backwards compatibility.

Let’s look at a code example.

SDK 9 (Android 2.3/Gingerbread) introduced “Strict Mode” which prints warnings when apps do things they shouldn’t do. Strict Mode requires apps opt-in, but the method to opt-in is only available on SDK 9 or later.

This example is compatible with Android 1.5 and later. It checks the SDK level and then uses reflection to enable Strict Mode for supported versions of Android. This is ugly, complicated, and doesn’t give the developer compile time checks.

public class AndroidTestActivity extends Activity{ /** Called when the activity is first created. */ @Override public void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main);

// Only for Gingerbread or later if (android.os.Build.VERSION.SDK_INT > 9) { StrictMode.enableDefaults(); } }}

Android 2.0’s virtual machine is much more lax about handling classes that it doesn’t recognize. When this is run on API 5 through 8, Dalvik will print out a warning to logcat but otherwise this runs fine and is much simpler.

#2Single app store

Only distribute your app through a single app store: Android Market.

The first problem is administrative: Every time you update your app you have to upload it to multiple app stores. That’s a lot of additional overhead, especially considering that many app stores have different requirements.

In addition, multiple app stores provide a poor user experience.

If users buy your app from a carrier-specific app store, what happens when they switch carriers? What happens if they move to another country? Here’s what happens: they lose access to their apps and then they email you for support and demand that you transfer their apps to the Android Market, which isn’t possible.

#3Be explicit

    <supports-screens        android:anyDensity="true"        android:largeScreens="true"        android:normalScreens="true"        android:smallScreens="true"        android:xlargeScreens="true"/>

The Android documentation currently states that for apps that target SDK level 4 or greater, the support-screens entry defaults to true for all entries. In reality, this behavior is undefined. To ensure your app is visible to all users, explicitly set supports-screens Android Manifest entry.

android:hardwareAccelerated="false"

Honeycomb introduced hardware acceleration as an option feature and ICS turns this on by default. What isn’t well documented is the fact that hardware acceleration can significantly increase the memory usage of your application.

As a foreground app, this probably doesn’t matter. But if your application has a background component you should seriously consider what happens.

<activity android:name=".ui.EditActivity" android:exported="true" android:icon="@drawable/ic_locale_plugin" android:label="@string/plugin_name" android:theme="@style/Theme.Locale.Dark" android:uiOptions="splitActionBarWhenNarrow" >

<intent-filter> <action android:name="com.twofortyfouram.locale.intent.action.EDIT_SETTING" /> </intent-filter> </activity>

<receiver android:name=".receiver.FireReceiver" android:exported="true" android:process=":background" >

<intent-filter> <action android:name="com.twofortyfouram.locale.intent.action.FIRE_SETTING" /> </intent-filter> </receiver>

Locale’s plug-in examples run background processing in a different process that never touches the UI, to ensure the background process never has the hardware acceleration memory overhead.

#4Scale up and down

Different devices have different characteristics, so your Android app should be able to scale up and down based on what features are available.

context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_SENSOR_ACCELEROMETER))

“android.hardware.sensor.accelerometer”

<uses-library android:name="com.google.android.maps" android:required="false" />

try{ Class.forName("com.google.android.maps.MapActivity"); //$NON-NLS-1$ startActivity(new Intent(getIntent()).setClass(getApplicationContext(), LocationConditionActivityGoogleMaps.class));}catch (final Exception e){ /* * A ClassNotFound exception is usually what occurs, but other strange exceptions have also been observed */ startActivity(new Intent(getIntent()).setClass(getApplicationContext(), LocationConditionActivityNoMaps.class));}

#5Configuration control

#6Unit tests

#7Buy, beg, and borrow

It is important to test as many devices as possible. Buy some devices, then beg friends, family, and other developers to borrow devices.

Some manufacturers, like Sony Ericsson, have a device loaner program.

#8Phased rollout

Use Android Market’s multi-APK feature to roll out a new version of an app to a smaller subset of users initially.

http://developer.android.com/resources/dashboard/platform-versions.html

For example, Android 4.0+ is only 1% of the user base and would be a great place to start a phased rollout of an app update.

#9Tools

Android Lint, Findbugs, etc.

http://www.android-permissions.org/

#10Bugs to watch out for

Samsung Ringtone Picker Crash

final Intent pickerIntent = new Intent(RingtoneManager.ACTION_RINGTONE_PICKER);pickerIntent.putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_DEFAULT, false);pickerIntent.putExtra(RingtoneManager.EXTRA_RINGTONE_TYPE, RingtoneManager.TYPE_RINGTONE);pickerIntent.putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_SILENT, false);

startActivity(pickerIntent);

Setting RingtoneManager.EXTRA_RINGTONE_SHOW_SILENT causes a crash on Samsung Galaxy S/Galaxy S II devices.

Intent security

public class AndroidTestActivity extends Activity{ /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);

startActivity(new Intent(Settings.ACTION_WIFI_SETTINGS).putExtra("serializable", new CustomSerializable())); }

private static final class CustomSerializable implements Serializable { private static final long serialVersionUID = 1L; }

}

http://code.google.com/p/android/issues/detail?id=16006

Sensor Accuracy

Certain devices like the Kyocera Echo and the Motorola Xoom always report that the accelerometer is inaccurate but that isn’t true.