Mtc spring 2014 best practices to develop for different android device classifications

Preview:

Citation preview

Hasan Hosgel | ImmobilienScout24

Best Practices to develop for different Android Device Classifications

ImmobilienScout24

Germany’s largest real estate listing company.

> 10 Mio. Monthly unique users> 1.5 Mio. real estates> 300 Mio. detail views> 1500 Servers~ 7.5 Mio. App downloads

> 3 Mio. Android> 50% mobile traffic

Fragmentation

Fragmentation

> 5000 Android Devices

Here comes the Nightmare

Image source:http://www.flickr.com/photos/boogeyman13/4553188509/

Image source:http://www.flickr.com/photos/boogeyman13/4553188509/

Here comes the Nightmare

For developers

Let’s build the fundament

Image source:http://www.flickr.com/photos/hertenberger/1434191066/

Device Classification

Image source:https://play.google.com/store/devices

Image source:https://play.google.com/store/deviceshttp://www.htc.com

Image source:http://www.sony.de/hub/google-tv

Image source:https://developer.ford.com/

Open Automotive AllianceStarting 2014 several companies plan to bring Android platform to the cars.• Audi• GM• Google• Honda• Hyundai• Nvidiahttp://www.openautoalliance.net/

Wearables

Android Wear SDK

Google Glass

Hard Work Ahead

Image source:http://www.flickr.com/photos/16210667@N02/9172895225

Resource Folders

You can use several qualifiers in the resource folders name for serving the best matching resource.

Qualifiers• Language (-en)• Language & Region (-en-rUS)• Smallest Width (–sw600dp)• Screensize (-small, -normal, -large)• Screen Orientation (-port, -land)• Screen Pixel Densitiy (-hdpi, -xxhdpi,…)• Platform Version (-v11, -v13)

Best Matching Resource Wins1. res/values/strings.xml2. res/values-en-rUS/strings.xml3. res/values-large/strings.xml4. res/values-sw600dp/strings.xml

Best Matching Resource Wins1. res/values/strings.xml2. res/values-en-rUS/strings.xml3. res/values-large/strings.xml4. res/values-sw600dp/strings.xml

The order of the qualifiers in the previous slides gives the ranking, if two resources have the same matching number of qualifiers.

Image Resources• Use the different qualifiers for the screen pixel

density (mdpi, hdpi, etc.)• If you are forced to use text on images use

language and region (en, es-rUS, en-rUS, etc.)• Better approach is to use 9-patch drawables,

which stretches automatically depending on the content inside.

• You must provide different launcher icons for Froyo, Honeycomb and above? Use the platform version. (v4, v11, v14)

Classifications for Layouts

Platform version at least v13 (Honeycomb MR2)

Classifications for Layouts

Platform version at least v13 (Honeycomb MR2)

project-folder/res/

layout/

Classifications for Layouts

Platform version at least v13 (Honeycomb MR2)

project-folder/res/

layout/ small phones

Classifications for Layouts

Platform version at least v13 (Honeycomb MR2)

project-folder/res/

layout/ small phones

layout-sw320dp/ other phones

Classifications for Layouts

Platform version at least v13 (Honeycomb MR2)

project-folder/res/

layout/ small phones

layout-sw320dp/ other phones

layout-sw600dp/ tablets 7”

Classifications for Layouts

Platform version at least v13 (Honeycomb MR2)

project-folder/res/

layout/ small phones

layout-sw320dp/ other phones

layout-sw600dp/ tablets 7”

layout-sw720dp/ tablets 10”

* You should also use the orientation qualifier

Platform version lower v11

project-folder/res/

layout/

layout-sw320dp/ other phones

layout-sw600dp/ tablets 7”

layout-sw720dp/ tablets 10”

Platform version lower v11

project-folder/res/

layout/ phones

layout-sw320dp/ other phones

layout-sw600dp/ tablets 7”

layout-sw720dp/ tablets 10”

Platform version lower v11

project-folder/res/

layout/ phones

layout-v11/ tablets 10”

layout-sw320dp/ other phones

layout-sw600dp/ tablets 7”

layout-sw720dp/ tablets 10”

Platform version lower v11

project-folder/res/

layout/ phones

layout-v11/ tablets 10”

layout-v13/ small phones

layout-sw320dp/ other phones

layout-sw600dp/ tablets 7”

layout-sw720dp/ tablets 10”

Hint

The smallest width qualifier gets automatically platform version ”-v13” through the packager, for avoiding problems with the number of matching qualifiers.

How to Classify In Code• Read configuration from the device

How to Classify In Code• Read configuration from the device• Smarter approach is to use boolean

resources

project-folder/res/values/layouts.xml

<resources>

</resources>

project-folder/res/values/layouts.xml

<resources>

<bool > </bool>

</resources>

project-folder/res/values/layouts.xml

<resources>

<bool name="is_phone_small"> </bool>

</resources>

project-folder/res/values/layouts.xml

<resources>

<bool name="is_phone_small">true</bool>

</resources>

project-folder/res/values/layouts.xml

<resources>

<bool name="is_phone_small">true</bool>

<bool name="is_phone_other">false</bool>

<bool name="is_tablet_7">false</bool>

<bool name="is_tablet_10">false</bool>

</resources>

project-folder/res/values/layouts.xml

<resources>

<bool name="is_phone_small">true</bool>

<bool name="is_phone_other">false</bool>

<bool name="is_tablet_7">false</bool>

<bool name="is_tablet_10">false</bool>

</resources>

Usage in code: getResources().getBoolean(R.bool.is_phone_small)

Current Layout File Structureproject-folder/res/

layout/main.xmllayout-v11/main.xmllayout-v13/main.xmllayout-sw320dp/main.xmllayout-sw600dp/main.xmllayout-sw720dp/main.xml

Current Layout File Structureproject-folder/res/

layout/main.xmllayout-v11/main.xmllayout-v13/main.xmllayout-sw320dp/main.xmllayout-sw600dp/main.xmllayout-sw720dp/main.xml

Fixing one bug in the 10“ layout has to be done in two files.

Current Layout File Structureproject-folder/res/

layout/main.xmllayout-v11/main.xmllayout-v13/main.xmllayout-sw320dp/main.xmllayout-sw600dp/main.xmllayout-sw720dp/main.xml

Fixing one bug in the 10“ layout has to be done in two files. error prone

Resource Alias

Put your layout files in the default folder.project-folder/res/

layout/main_phone_small.xml

layout/main_phone_other.xml

layout/main_tablet_7.xml

layout/main_tablet_10.xml

Create an item with the needed classification in the previously defined values folder.

project-folder/res/values-sw720dp/layouts.xml

<resources>

</resources>

Create an item with the needed classification in the previously defined values folder.

project-folder/res/values-sw720dp/layouts.xml

<resources>

<item name="main" >

</item>

</resources>

Create an item with the needed classification in the previously defined values folder.

project-folder/res/values-sw720dp/layouts.xml

<resources>

<item name="main" type="layout">

</item>

</resources>

Create an item with the needed classification in the previously defined values folder.

project-folder/res/values-sw720dp/layouts.xml

<resources>

<item name="main" type="layout">

@layout/main_tablet_10.xml

</item>

</resources>

Scenario

Use <includes>

Usage include<LinearLayout … >

…< />…

</LinearLayout>

Usage include<LinearLayout … >

…<include />…

</LinearLayout>

Usage include<LinearLayout … >

…<include layout="@layout/footer"/>…

</LinearLayout>

Use <includes>

Use <includes>

Custom Viewpublic class CustomView extends LinearLayout {…

public CustomView(Context context, AttributeSet attrs) {

addView(createTextView(context, "label"), lp);

addView(createTextView(context, "desc"), lp);

if(getResources().getBoolean(R.bool.is_phone)){setOrientation(VERTICAL);

} else {setOrientation(HORIZONTAL);

}}

}

Usage In Layout Files<LinearLayout … >

…<de.alosdev.CustomViewandroid:layout_width="wrap_content" android:layout_height="wrap_content"/>…

</LinearLayout>

Use <includes>

Create custom view

Custom XML Attribute<resources> <resources>

Custom XML Attribute<resources> <declare-styleable > </declare-styleable><resources>

Custom XML Attribute<resources> <declare-styleable name=”CustomView"> </declare-styleable><resources>

Custom XML Attribute<resources> <declare-styleable name=”CustomView"> <attr /> </declare-styleable><resources>

Custom XML Attribute<resources> <declare-styleable name=”CustomView"> <attr name="label" /> </declare-styleable><resources>

Custom XML Attribute<resources> <declare-styleable name=”CustomView"> <attr name="label" format="reference|string"/> </declare-styleable><resources>

Custom XML Attribute<resources> <declare-styleable name=”CustomView"> <attr name="label" format="reference|string"/> <attr name="value" format="reference|string"/> </declare-styleable><resources>

Custom XML Attribute<resources> <declare-styleable name=”CustomView"> <attr name="label" format="reference|string"/> <attr name="value" format="reference|string"/> <attr name="orientation" format="enum"> <enum name="horizontal" value="0"/> <enum name="vertical" value="1"/> </attr> </declare-styleable><resources>

Usage In Layout Files

1. Add to root XML nodexmlns:app="http://schemas.android.com/apk/res-auto"

Usage In Layout Files

1. Add to root XML nodexmlns:app="http://schemas.android.com/apk/res-auto"

2. Usage in custom view<de.alosdev.CustomView android:id="@+id/customView" android:layout_width="wrap_content" android:layout_height="wrap_content" app:label="label 1" app:orientation="vertical" app:value="value 1" />

public class CustomView extends LinearLayout { static final int[] ORIENTATION = new int[] { HORIZONTAL, VERTICAL }; public CustomView(Context context, AttributeSet attrs) { super(context, attrs); …

TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CustomView); try { setOrientation(ORIENTATION[ a.getInt(R.styleable.CustomView_orientation, 0)]); } finally { a.recycle(); } } …

}

If custom view has much more business logic and need lifecycles Create a Fragment

Code

Best Practices

You have already an application Remove orientation fixation and suppressing of orientation change from manifest to avoid long bug analyzing.

You start from the scratch Focus on main classification for faster time to market But create an overall concept for better modularization

If you support both orientations, save the instance state while orientation changes for more responsiveness

Especially for states, that need a long computation for creation.Make the state object Parcelable for faster write & read and also to have a smaller memory footprint

Developer Hints• You can start an activity for result from a

fragment, so the response can be handled in the fragment.

• If you want to register a special service on every onCreate method of an activity give the ActivityLivecycleCallbacks a try. You can register them in the onCreate method of the application. (minSDK -v14)

If you get a BadParcelableException with the cause ClassNotFound-Exception, the source can be a NullPointerException during the read or write of the Parcelable. Exceptions are hidden during the parcel process.

If you want to use “match_parent” or “wrap_content” in a dimension alias, you should use “-1px” or “-2px”

project-folder/res/values/dimen.xml<resources> <dimen name="my_dimen>@dimen/match_parent</dimen> <dimen name="match_parent">-1px</dimen> <dimen name="wrap_content">-2px</dimen></resources>

project-folder/res/values-sw600dp/layout.xml<resources> <dimen name="my_dimen>300dp</dimen></resources>

Listener HellIf you have to many listeners or you think the programming model is old school like the “goto statements”. Give message/ event/ service bus a try. For Android:• Otto from Square• EventBus from greenrobot

See also: Callbacks as our Generations' Go To Statement

Holo Color Generator

Mission Accomplished?

Image source:http://www.flickr.com/photos/ianaberle/5729561934/

Mission Accomplished

cleared

Image source:http://www.flickr.com/photos/ianaberle/5729561934/

Q & A

Image source:http://www.flickr.com/photos/21496790@N06/5065834411/

www.immobilienscout24.dewww.immobilienscout24.de

Thanks for your attention!

Contact:+HasanHosgel

@alosdev

alosdev

Best Practices to develop for different Android Device Classificationshttps://github.com/alosdev/multidevice-nightmare-demohttp://www.slideshare.net/hosgel/mtc-spring-2014-best-practices-to-develop-for-different-android-device-classifications