vk.amberfog.com gtug part1_introduction2_javaandroid_gtug

95
Introduction (part I): Java and Android basics Alexey Golubev, Dmitry Lukashev

Upload: ketanpatel25

Post on 09-May-2015

703 views

Category:

Technology


0 download

TRANSCRIPT

Page 1: Vk.amberfog.com gtug part1_introduction2_javaandroid_gtug

Introduction (part I): Java and Android basics

Alexey Golubev, Dmitry Lukashev

Page 2: Vk.amberfog.com gtug part1_introduction2_javaandroid_gtug

What is the plan?

Part I Part II Part III

Android UI

Layouts, ListView,

Menu, Dialog, Widgets, Tips & tricks, etc.

Android in Action

Screen rotation, Memory analyze, AIDL, SAX, Debug,

Wakelock, etc.

Java +Android (basics)

JVM, GC, Threads, SDK, NDK, Activity,

Code style, etc.

Page 3: Vk.amberfog.com gtug part1_introduction2_javaandroid_gtug

Part I: Introduction

What is this about?

• Introduction to Java world

• JVM, Dalvik VM, JIT

• GC, multithreading, collections, etc.

• Android Basics

• Architecture

• Building blocks, SDK, NDK, etc.

• NDK demo

Page 4: Vk.amberfog.com gtug part1_introduction2_javaandroid_gtug

Java overview

• Sun VM, Dalvik VM, JIT

• Garbage collection

• References

• Exceptions

• Threads

• Synchronization

• Collections

• Wrapper classes

• Java and Android code style

Page 5: Vk.amberfog.com gtug part1_introduction2_javaandroid_gtug

Where to start

• http://developer.android.com/

• http://source.android.com/

• http://android.git.kernel.org/

• http://android-developers.blogspot.com/

Page 6: Vk.amberfog.com gtug part1_introduction2_javaandroid_gtug

Java overview

• Sun VM, Dalvik VM, JIT

• Garbage collection

• References

• Exceptions

• Threads

• Synchronization

• Collections

• Wrapper classes

• Java and Android code style

Page 7: Vk.amberfog.com gtug part1_introduction2_javaandroid_gtug

JVM

The pc register (program counter)

JVM Stack

Native methods stacks

Heap

Method Area VM

Thread

Сlass Runtime Constant Pool

class files Class loader subsystem

native method libraries

Execution engine

Native method interface

Page 8: Vk.amberfog.com gtug part1_introduction2_javaandroid_gtug

Dalvik VM

• Was written by Dan Bornstein

• Transform class files into DEX

• It is VM… – integrated with Linux

– uses shared memory, mmap

– for OS without swap space

– while powered by a battery

– zygote

• The Dalvik VM is register-based: fewer instructions, code units, instructions

• Verification & optimization at installation time

Give me your huddled bytecodes

yearning to run free. And I lift

the light beside the coder’s door

Page 9: Vk.amberfog.com gtug part1_introduction2_javaandroid_gtug

DEX file – shared constant pool

.jar file

.dex file heterogeneous constant pool

other data

.class file

heterogeneous constant pool

other data

.class file

heterogeneous constant pool

other data

.class file

string_ids constant pool

type_ids constant pool

proto_ids constant pool

field_ids constant pool

method_ids constant pool

other data

“Hello World”

“Lcom/data/Data”

int

String[ ]

String fn()

void fn(int)

String.offset

Integer.MAX_VALUE

PrintStream.println(…)

Collection.size()

Page 10: Vk.amberfog.com gtug part1_introduction2_javaandroid_gtug

DEX file – memory saving

• minimal repetition

• per-type pools (implicit typing)

• implicit labeling

common system libraries

(U) 21445320 — 100% (uncompressed jar file)

(J) 10662048 — 50% (compressed jar file)

(D) 10311972 — 48% (uncompressed dex file)

web browser app

(U) 470312 — 100%

(J) 232065 — 49%

(D) 209248 — 44%

• Google claims that Dalvik bytecode is more efficient than Sun’s stack

bytecode

Page 11: Vk.amberfog.com gtug part1_introduction2_javaandroid_gtug

JIT (since Android 2.2)

• Translates byte code to optimized native code at run time

• Part of the open source

• Trace JIT vs Method JIT

• Trace JIT – Minimizing memory usage critical for mobile devices (100K)

– Important to deliver performance boost quickly

– Trace request is built during interpretation

– Compiled traces chained together in translation cache

– Per process translation cache

• Leave open the possibility of supplementing with method-based JIT

Page 12: Vk.amberfog.com gtug part1_introduction2_javaandroid_gtug

Java overview

• Sun VM, Dalvik VM, JIT

• Garbage collection

• References

• Exceptions

• Threads

• Synchronization

• Collections

• Wrapper classes

• Java and Android code style

Page 13: Vk.amberfog.com gtug part1_introduction2_javaandroid_gtug

Garbage collection

• GC is under control of the JVM • An object is eligible for garbage

collection when no live thread can access it

• System.gc(); Runtime.getRuntime().gc()

• static – variables with the longest life time

public class Island {

Island i;

public static void main(String[] args) {

Island i2 = new Island();

Island i3 = new Island();

Island i4 = new Island();

i2.n = i3; i3.n = i4; i4.n = i2;

i2 = null; i3 = null; i4 = null;

Island x = new Island(); x = null;

}

}

i4.n

i3.n

i2.n

i2

i3

i4

The heap

x

“Islands of Isolation”

Page 14: Vk.amberfog.com gtug part1_introduction2_javaandroid_gtug

Mark and Sweep example

• Obtain locks and suspend threads

• Mark phase

– Process of identifying all objects reachable from the root set.

– All “live” objects are marked by setting a mark bit in the mark bit vector.

• Sweep phase

– Sweep phase identifies all the

objects that have been allocated,

but no longer referenced.

• Compaction (optional)

– Once garbage has been removed,

we consider compacting the

resulting set of objects to remove

spaces between them.

• Release locks and resume threads

Parallel mark bits in Dalvik VM (separate from other heap memory)

Page 15: Vk.amberfog.com gtug part1_introduction2_javaandroid_gtug

Generational GC

• Most recently created objects – most likely to become unreachable quickly

Young Generation Old Generation

• Minor Collection – takes place only in the young generation,

normally done through direct copying – very efficient

• Major Collection – takes place in the new and old generation

and uses the normal mark/sweep (+compact) algorithm

Page 16: Vk.amberfog.com gtug part1_introduction2_javaandroid_gtug

Strings

• Strings are immutable in Java

The heap

“Hi”

x

String x = “Hi";

x = x.concat(" GTUG!");

The heap

“Hi”

x

“Hi GTUG”

String s1 = "abc"; // 1 object, 1 reference

String s2 = "abc";

// s1 == s2

String s3 = new String("abc"); // 2

objects, 1 reference

String s4 = new String("abc");

// s3 != s4

// optimization by interning strings

s3 = s3.intern();

s4 = s4.intern();

• Use StringBuffer, StringBuilder

• Set initial capacity of StringBuilder

Page 17: Vk.amberfog.com gtug part1_introduction2_javaandroid_gtug

Quiz

class Foo {

int[] mArray = {

1, 2, 3, 4, 5

};

}

public class Test {

public static void main(String[] args) {

Foo[] fa = new Foo[3];

fa[0] = new Foo();

Foo f = new Foo();

fa[1] = f;

f = null;

fa[1] = null;

// how many objects were created at this point?

// how many are eligible for gc()?

}

}

[ ref0, ref1, ref2]

[ ] Foo()

[ ] Foo()

Page 18: Vk.amberfog.com gtug part1_introduction2_javaandroid_gtug

Performance

• Do not allocate memory as much as you can

• GC is slow (~x00 ms on Android device)

• Decrease number of objects – GC will work faster (i.e. StringBuffer vs String)

• Use primitive types for arrays (int vs Integer)

• Use special methods: String.indexOf(), substring(), etc.

• Use exact class types instead of interfaces (i.e. HashMap instead of Map) on devices without JIT

• Use static where possible

• Avoid internal getters/setters

• Use enhanced for-loop syntax

ArrayList<MyClass> mList = new

ArrayList<MyClass>();

...

for (MyClass next : mList) {

...

}

Page 19: Vk.amberfog.com gtug part1_introduction2_javaandroid_gtug

Java overview

• Sun VM, Dalvik VM, JIT

• Garbage collection

• References

• Exceptions

• Threads

• Synchronization

• Collections

• Wrapper classes

• Java and Android code style

Page 20: Vk.amberfog.com gtug part1_introduction2_javaandroid_gtug

References

• Strong reference: Object obj = new Object();

• SoftReference – soft references will be cleared before the JVM reports an out-of-memory condition (memory-sensitive cache)

• WeakReference – gc frees weakly reachable object when it founds it, avoid memory leaks (e.g. http://en.wikipedia.org/wiki/Flyweight_pattern)

• PhantomReference – is useful only to track the impending collection of the referring object. Must be used only with the ReferenceQueue class. Most often used for scheduling pre-mortem cleanup actions in a more flexible way than is possible with the Java finalization mechanism

Page 21: Vk.amberfog.com gtug part1_introduction2_javaandroid_gtug

SoftReference: simple cache

private final HashMap<String, SoftReference<T>> mCache;

public put(String key, T value) {

mCache.put(key, new SoftReference<T>(value));

}

public T get(String key, ValueBuilder builder) {

T value = null;

SoftReference<T> reference = mCache.get(key);

if (reference != null) {

value = reference.get();

}

// Not in cache or gc'd

if (value == null) {

value = builder.build(key);

mCache.put(key, new SoftReference<T>(value));

}

return value;

}

Page 22: Vk.amberfog.com gtug part1_introduction2_javaandroid_gtug

package com.android.mms.model;

public class ImageModel extends RegionMediaModel {

private static final String TAG = "Mms/image";

private static final int THUMBNAIL_BOUNDS_LIMIT = 480;

private SoftReference<Bitmap> mBitmapCache = new SoftReference<Bitmap>(null);

...

private Bitmap internalGetBitmap(Uri uri) {

Bitmap bm = mBitmapCache.get();

if (bm == null) {

try {

bm = createThumbnailBitmap(THUMBNAIL_BOUNDS_LIMIT, uri);

if (bm != null) {

mBitmapCache = new SoftReference<Bitmap>(bm);

}

} catch (OutOfMemoryError ex) {

// fall through and return a null bitmap.

// The callers can handle a null

// result and show R.drawable.ic_missing_thumbnail_picture

}

}

return bm;

}

}

git://android.git.kernel.org/platform/packages/apps/Mms.git/src/com/android/mms/model/ImageModel.java

SoftReference

Page 23: Vk.amberfog.com gtug part1_introduction2_javaandroid_gtug

package android.app;

public class Dialog implements DialogInterface, Window.Callback,

KeyEvent.Callback, OnCreateContextMenuListener {

...

private static final class ListenersHandler extends Handler {

private WeakReference<DialogInterface> mDialog;

public ListenersHandler(Dialog dialog) {

mDialog = new WeakReference<DialogInterface>(dialog);

}

@Override

public void handleMessage(Message msg) {

switch (msg.what) {

case DISMISS:

((OnDismissListener) msg.obj).onDismiss(mDialog.get());

break;

case CANCEL:

((OnCancelListener) msg.obj).onCancel(mDialog.get());

break;

case SHOW:

((OnShowListener) msg.obj).onShow(mDialog.get());

break;

}

}

}

}

git://android.git.kernel.org/platform/frameworks/base.git/core/java/android/app/Dialog.java

WeakReference

Page 24: Vk.amberfog.com gtug part1_introduction2_javaandroid_gtug

finalize()

• The finalize() method is guaranteed to run once and only once before GC deletes an object

• GC makes no guarantees, finalize() may never run

• You can uneligibilize an object for GC within finalize()

• Do not use it for resource closing

Page 25: Vk.amberfog.com gtug part1_introduction2_javaandroid_gtug

Java overview

• Sun VM, Dalvik VM, JIT

• Garbage collection

• References

• Exceptions

• Threads

• Synchronization

• Collections

• Wrapper classes

• Java and Android code style

Page 26: Vk.amberfog.com gtug part1_introduction2_javaandroid_gtug

Exceptions

try {

// do stuff

} catch (SomeException e) {

// do exception handling

} finally {

// clean up

}

try {

// do stuff

} finally {

// clean up

}

Object

Throwable

Exception Error

RuntimeException AssertionError StackOverflowError OutOfMemoryError NullPointerException IndexOfBoundException IOException SQLiteException

Page 27: Vk.amberfog.com gtug part1_introduction2_javaandroid_gtug

try/catch/finally (1)

class Test {

private String data = "test";

private int test() {

try {

System.out.println(data.length());

return 0;

} catch (NullPointerException e) {

System.out.println("exception");

return 1;

} finally {

System.out.println("finally");

return 2;

}

}

public static void main(String[] args) {

Test t = new Test();

System.out.println("result = " + t.test());

}

}

4

finally

result = 2

Page 28: Vk.amberfog.com gtug part1_introduction2_javaandroid_gtug

try/catch/finally (2)

class Test {

private String data;

private int test() {

try {

System.out.println(data.length());

return 0;

} catch (NullPointerException e) {

System.out.println("exception");

return 1;

} finally {

System.out.println("finally");

return 2;

}

}

public static void main(String[] args) {

Test t = new Test();

System.out.println("result = " + t.test());

}

}

exception

finally

result = 2

Page 29: Vk.amberfog.com gtug part1_introduction2_javaandroid_gtug

DefaultExceptionHandler

public class DefaultExceptionHandler implements UncaughtExceptionHandler {

private UncaughtExceptionHandler mDefaultExceptionHandler;

public DefaultExceptionHandler(UncaughtExceptionHandler pDefaultExceptionHandler)

{

mDefaultExceptionHandler = pDefaultExceptionHandler;

}

public void uncaughtException(Thread t, Throwable e) {

mDefaultExceptionHandler.uncaughtException(t, e);

t.getThreadGroup().destroy();

}

}

Thread.setDefaultUncaughtExceptionHandler(new

DefaultExceptionHandler(Thread.getDefaultUncaughtExceptionHandler()));

Page 30: Vk.amberfog.com gtug part1_introduction2_javaandroid_gtug

Java overview

• Sun VM, Dalvik VM, JIT

• Garbage collection

• References

• Exceptions

• Threads

• Synchronization

• Collections

• Wrapper classes

• Java and Android code style

Page 31: Vk.amberfog.com gtug part1_introduction2_javaandroid_gtug

Threads

• When it comes to threads, very little is guaranteed

• Create thread: extend java.lang.Thread or implement Runnable interface

• A thread is done being a thread when its target run() method completes

• Once a thread has been started, it can never be started again

• The order in which runnable threads are chosen is not guaranteed

• sleep(long ms), yield(), join(), setPriority(int priority), wait(), notify(), notifyAll()

Page 32: Vk.amberfog.com gtug part1_introduction2_javaandroid_gtug

Thread states

New Runnable Running

Waiting/

blocking

Dead

not alive alive not alive

run() completes start()

wait, sleep, join, lock

yield

Page 33: Vk.amberfog.com gtug part1_introduction2_javaandroid_gtug

Java overview

• Sun VM, Dalvik VM, JIT

• Garbage collection

• References

• Exceptions

• Threads

• Synchronization

• Collections

• Wrapper classes

• Java and Android code style

Page 34: Vk.amberfog.com gtug part1_introduction2_javaandroid_gtug

Synchronization

• Every Object in java has build-in lock

• Only methods or blocks can be synchronized public static synchronized int getCount() {

return count;

}

public static int getCount() {

synchronized(MyClass.class) { // Class c = Class.forName(“MyClass”);

return count;

}

}

• notify(), join(), sleep(), yield() keep locks, wait() gives up lock

• synchronized keyword is not automatically inherited when

subclasses override superclass method

Page 35: Vk.amberfog.com gtug part1_introduction2_javaandroid_gtug

Volatile

public class Task extends Thread {

private volatile boolean mIsStop;

public void run() {

while (!mIsStop) {

// do some stuff...

}

}

public void stopMe() {

mIsStop = true;

}

}

volatile:

• Every thread accessing the field will read its current value before continuing, instead of (potentially) using a cached value

• Statements accessing the variable will be executed in the order they are written (Java 5 or later)

class VolatileExample {

int x = 0;

volatile boolean v = false;

public void writer() {

x = 42;

v = true;

}

public void reader() {

if (v == true) {

// uses x - guaranteed to see 42.

}

}

}

Page 36: Vk.amberfog.com gtug part1_introduction2_javaandroid_gtug

Singleton pattern example (1)

public class Singleton {

private static final Singleton INSTANCE = new Singleton();

private Singleton() {}

public static Singleton getInstance() {

return INSTANCE;

}

} thread-safe

public class Singleton {

private static Singleton sInstance;

private Singleton() {}

public static Singleton getInstance() {

if (sInstance == null) {

sInstance = new Singleton();

}

return sInstance;

}

} non-thread-safe

lazy init

Page 37: Vk.amberfog.com gtug part1_introduction2_javaandroid_gtug

Singleton pattern example (2)

public class Singleton {

private static Singleton sInstance;

private Singleton() {}

public synchronized static Singleton getInstance() {

if (sInstance == null) {

sInstance = new Singleton();

}

return sInstance;

}

}

lazy init

thread-safe

low performance

Page 38: Vk.amberfog.com gtug part1_introduction2_javaandroid_gtug

Singleton pattern example (3)

public class Singleton {

private static Singleton sInstance;

private Singleton() {}

public static Singleton getInstance() {

if (sInstance == null) {

synchronized (Singleton.class) {

if (sInstance == null) {

sInstance = new Singleton();

}

}

}

return sInstance;

}

}

if (sInstance == null) { // “Double-Checked Locking” idiom

}

Page 39: Vk.amberfog.com gtug part1_introduction2_javaandroid_gtug

Singleton pattern example (4)

public class Singleton {

private volatile static Singleton sInstance;

private Singleton() {}

public static Singleton getInstance() {

if (sInstance == null) {

synchronized (Singleton.class) {

if (sInstance == null) {

sInstance = new Singleton();

}

}

}

return sInstance;

}

} lazy init & thread-safe (Java 5 or later)

Page 40: Vk.amberfog.com gtug part1_introduction2_javaandroid_gtug

Singleton pattern example (5)

public class Singleton {

private Singleton() {}

private static class SingletonHolder {

private static final Singleton INSTANCE = new Singleton();

}

public static Singleton getInstance() {

return SingletonHolder.INSTANCE;

}

}

lazy init & thread-safe (for all Java version)

Page 41: Vk.amberfog.com gtug part1_introduction2_javaandroid_gtug

Quiz

public class Foo {

private static final int DELTA = 6;

private static Foo sInstance = new Foo();

private static int sBase = 7;

private int mX;

private Foo() {

mX = sBase + DELTA;

}

public static void main(String[] args) {

System.out.println(Foo.sInstance.mX);

}

}

What is the print? 6

Page 42: Vk.amberfog.com gtug part1_introduction2_javaandroid_gtug

Java overview

• Sun VM, Dalvik VM, JIT

• Garbage collection

• References

• Exceptions

• Threads

• Synchronization

• Collections

• Wrapper classes

• Java and Android code style

Page 43: Vk.amberfog.com gtug part1_introduction2_javaandroid_gtug

Collection

Set List Queue

HashSet

LinkedHashSet

SortedSet

NavigableSet

TreeSet

ArrayList Vector LinkedList PriorityQueue

Map

SortedMap

NavigableMap

TreeMap LinkedHashMap

HashMap HashTable

Collections

1.6

1.6

WeakHashMap ConcurrentHashMap CopyOnWriteArraySet etc…

Page 44: Vk.amberfog.com gtug part1_introduction2_javaandroid_gtug

Alex Alex

Hash table

• Choosing a good hash function

• Collision resolution: separate chaining, open addressing

• Load factor

Key Hashcode Algorithm Hashcode

Alex A(1)+L(12)+E(5)+X(24) 42

Bob B(2)+O(15)+B(2) 19

Dirk D(4)+I(9)+R(18)+K(11) 42

Fred F(6)+R(18)+E(5)+D(4) 33

19

33

Bob

Fred

42 Dirk

19

33

Bob

Fred

42

Dirk 43

• Find the right bucket (using hashCode())

• Search the bucket for the right element (using equals())

Page 45: Vk.amberfog.com gtug part1_introduction2_javaandroid_gtug

Contracts

The equals() contract

• Reflexive – x.equals(x)=true

• Symmetric – x.equals(y)=true -> y.equals(x)=true

• Transitive – x.equals(y)=true, y.equals(z)=true -> x.equals(z)=true

• Consistent – multiple invocations

• x.equals(null)=false

The hashCode() contract

• Consistent during the app execution

• If x.equals(y) -> hash must be the same

@Override

public int hashCode() {

return 1;

}

Page 46: Vk.amberfog.com gtug part1_introduction2_javaandroid_gtug

Java overview

int

• Sun VM, Dalvik VM, JIT

• Garbage collection

• References

• Exceptions

• Threads

• Synchronization

• Collections

• Wrapper classes

• Java and Android code style

Page 47: Vk.amberfog.com gtug part1_introduction2_javaandroid_gtug

Wrapper Classes and Boxing (1)

Integer x = 100;

x++;

• The wrapper classes correlate to primitive types

• Wrappers have two main functions: – To wrap primitives so that they can be handled like objects

– To provide utility methods for primitives (conversions)

• Wrapper constructors can take String (except Character)

• As of Java 5, boxing allows to convert primitives to wrappers or vice versa automatically.

int x2 = x.intValue();

x2++;

x = new Integer(x2);

Page 48: Vk.amberfog.com gtug part1_introduction2_javaandroid_gtug

Wrapper Classes and Boxing (2)

Integer i1 = 1000;

Integer i2 = 1000;

if (i1 != i2) System.out.println("i1!=i2");

if (i1 == i2) System.out.println("i1==i2");

Integer i1 = 100;

Integer i2 = 100;

if (i1 != i2) System.out.println("i1!=i2");

if (i1 == i2) System.out.println("i1==i2");

JVM saves memory for:

• Boolean

• Byte

• Character from \u0000 to \u007f

• Short and Integer from -128 to 127

i1!=i2

I1==i2

Page 49: Vk.amberfog.com gtug part1_introduction2_javaandroid_gtug

Java overview

• Sun VM, Dalvik VM, JIT

• Garbage collection

• References

• Exceptions

• Threads

• Synchronization

• Collections

• Wrapper classes

• Java and Android code style

Page 50: Vk.amberfog.com gtug part1_introduction2_javaandroid_gtug

Java Code Style: why?

• 80% of the lifetime cost of a piece of software goes to maintenance

• Hardly any software is maintained for its whole life by the original author

• Code conventions improve the readability of the software, allowing engineers to understand new code more quickly and thoroughly

• Makes it easier to conduct code reviews

http://developers.sun.com/sunstudio/products/archive/whitepapers/java-style.pdf

Page 51: Vk.amberfog.com gtug part1_introduction2_javaandroid_gtug

Comments, TODOs, etc.

• Comments

• TODO, FIXME, XXX

– Use TODO comments for code that is temporary, a short-term solution, or good-enough but not perfect.

• Copyrights

Page 52: Vk.amberfog.com gtug part1_introduction2_javaandroid_gtug

Android Code Style (1)

• Import ordering – Android imports – Imports from third parties (com, junit, net, org) – java and javax

• Indentation – We use 4 space indents for blocks. We never use tabs. When in doubt,

be consistent with code around you – We use 8 space indents for line wraps, including function calls and

assignments

• Field Names – Non-public, non-static field names start with m. – Static field names start with s. – Other fields start with a lower case letter. – Public static final fields (constants) are ALL_CAPS_WITH_UNDERSCORES.

Page 53: Vk.amberfog.com gtug part1_introduction2_javaandroid_gtug

Android Code Style (2)

• Braces

– Braces do not go on their own line; they go on the same line as the code before them

• Line length

– Each line of text in your code should be at most 100 characters long.

• Annotations, Logging

http://source.android.com/submit-patches/code-style-guide

if (condition) {

body; // ok

}

if (condition) body; // ok - 1 line

if (condition)

body; // bad

Page 54: Vk.amberfog.com gtug part1_introduction2_javaandroid_gtug

BAD Code Style sample (1)

for(int i=0;i<amount;++i)

db.execSQL(sqls[i]);

public static final int sMaxSQLsInTransaction= 1000;

if (delayed == true) {

...

} else {

...

}

Good:

XmlHttpRequest getCustomerId

class Html

long id

Bad:

XMLHTTPRequest getCustomerID

class HTML

long ID

Page 55: Vk.amberfog.com gtug part1_introduction2_javaandroid_gtug

BAD Code Style sample (2)

public static final boolean PushValues(String pattern,

ArrayList<Integer> patternIds,/*OUT */ArrayList<String> values)

{

int idsAmount= (null != patternIds ? patternIds.size() : 0);

if(0<idsAmount){

final int patternLen=(null!=pattern ? pattern.length():0);

if(0<patternLen){

for(int i=0; i<idsAmount; ++i){

if(!pushValues(pattern,patternLen,patternIds.get(i),values)){

return (false);

}

}

return (true);

}

}

return (false);

}

Page 56: Vk.amberfog.com gtug part1_introduction2_javaandroid_gtug

BAD Code Style sample (2)

public static final ArrayList<String> getValues(final String pattern,

final ArrayList<Integer> patternIds) {

ArrayList<Integer> result = new ArrayList<Integer>();

if (pattern != null && pattern.length() > 0 && patternIds != null) {

for (int patternId : patternIds) {

ArrayList<Integer> values = getValuesForPatternId(pattern, patternId);

if (values == null) {

return null;

}

result.addAll(values);

}

}

return result;

}

Page 57: Vk.amberfog.com gtug part1_introduction2_javaandroid_gtug

Let’s Have a Break! 10 min

Page 58: Vk.amberfog.com gtug part1_introduction2_javaandroid_gtug

Android basics

• Architecture Overview

• Building Blocks

• Manifest

• System Services

• Platform versions

• Saving Application State

• NDK

• Make your code better

Page 59: Vk.amberfog.com gtug part1_introduction2_javaandroid_gtug

Android

• Architecture Overview

• Building Blocks

• Manifest

• System Services

• Platform versions

• Saving Application State

• NDK

• Make your code better

Page 60: Vk.amberfog.com gtug part1_introduction2_javaandroid_gtug

Android History

Sep 2008

1.0 Mar 2009

1.1 1.5

May 2009

1.6

Sep 2009

2.0

Oct 2009

2.0.1

Dec 2009

2.1

Jan 2010

2.2

May 2010

Cupcake Donut

Éclair

Froyo

Gingerbread

• Jul 2005 – Google acquired Android Inc. (co-founded by Andy Rubin)

• Nov 2007 – Google Android presentation and “early look” release

Page 61: Vk.amberfog.com gtug part1_introduction2_javaandroid_gtug

Android Architecture Overview

Linux Kernel

Display Driver

Keypad Driver

Camera Driver

WiFi Driver

Flash Memory Driver

Audio Drivers

Binder (IPC) Driver

Power Management

Libraries

Surface Manager Media Framework

OpenGL | ES FreeType

SQLite

WebKit

SGL SSL libc

Android Runtime

Core Libraries

Dalvik VM

Application Framework

Activity Manager

Package Manager

Window Manager

Telephony Manager

Content Providers

Notification Manager

View System

Location Manager

Resource Manager

Applications

Home Contacts Phone Browser …

ND

K /

JN

I

Page 62: Vk.amberfog.com gtug part1_introduction2_javaandroid_gtug

Android

• Architecture Overview

• Building Blocks

• Manifest

• System Services

• Platform versions

• Saving Application State

• NDK

• Make your code better

Page 63: Vk.amberfog.com gtug part1_introduction2_javaandroid_gtug

Android Application Building Blocks

• Activity – Presents UI – Each Activity is independent screen – Activity: setContentView(View)

• Service – Used for background operations

• BroadcastReceiver – Receive and process broadcast system or user events

• ContentProvider – Share application data with others – Data can be stored in FS, DB or even in memory – Communicate via ContentResolver

• Intent – Used to activate Activities, Services & BroadcastReceivers

http://developer.android.com/guide/topics/fundamentals.html

Page 64: Vk.amberfog.com gtug part1_introduction2_javaandroid_gtug

Android Application

• Controls global Application state

• Extend Application class (android.app.Application)

– onCreate()

– onLowMemory()

– onTerminate()

– getApplicationContext() – to use it in classes, where is no Context

• Point custom Application class in AndroidManifest.xml

Page 65: Vk.amberfog.com gtug part1_introduction2_javaandroid_gtug

Android Context

Application Context • Non UI Context

• startActivity(Intent)

• start /stopService(Intent)

• sendBroadcast(Intent)

• register / unregisterReciever()

• Application FS, Preferences, Resources

• getSystemService

Activity Context

• Same as for Application, but specific

to current Activity

• startActivityForResult(Intent) /

finish()

• bindService(Intent)

• UI: setContentView(View),

findViewById()

• User events handling (Keys,

Touches, Trackball)

Page 66: Vk.amberfog.com gtug part1_introduction2_javaandroid_gtug

Android

• Architecture Overview

• Building Blocks

• Manifest

• System Services

• Platform versions

• Saving Application State

• NDK

• Make your code better

Page 67: Vk.amberfog.com gtug part1_introduction2_javaandroid_gtug

AndroidManifest.xml (1)

<?xml version="1.0" encoding="utf-8"?>

<manifest

xmlns:android="http://schemas.android.com/apk/res/android"

package="com.my.example"

android:versionName="1.0 beta" android:versionCode="2">

<application android:name=".MyApplication"

android:label="..." android:icon="...">

<activity android:name=".MyActivity">

<intent-filter>

<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.DEFAULT" />

<category android:name="android.intent.category.LAUNCHER" />

</intent-filter>

</activity>

<service ... />

<receiver ... />

<provider ... />

</application>

</manifest>

Page 68: Vk.amberfog.com gtug part1_introduction2_javaandroid_gtug

AndroidManifest.xml (2)

<activity android:name=".MyActivity"

android:launchMode="singleTask"

android:theme="@style/Theme.MyDialog" />

<service android:name=".MyService" android:process="new"/>

<receiver android:name=".MyReceiver" >

<intent-filter>

<action android:name= "android.intent.action.PACKAGE_REMOVED" />

<category android:name= "android.intent.category.DEFAULT" />

<data android:scheme= "package" />

</intent-filter>

</receiver>

<provider android:name=".MyProvider"

android:authorities="com.my.provider" />

Page 69: Vk.amberfog.com gtug part1_introduction2_javaandroid_gtug

AndroidManifest.xml (3)

<?xml version="1.0" encoding="utf-8"?>

<manifest xmlns:android="..." package="com.my.example"

android:versionName="1.0 beta" android:versionCode="2">

<uses-permission android:name="android.permission.INTERNET" />

<uses-permission android:name="android.permission.BLUETOOTH" />

<uses-sdk

android:minSdkVersion="3"

android:targetSdkVersion="4"/>

<supports-screens

android:largeScreens="true"

android:normalScreens="true"

android:smallScreens="true"

android:resizeable="true"

android:anyDensity="true" />

<application ...> ... </application>

</manifest>

Page 70: Vk.amberfog.com gtug part1_introduction2_javaandroid_gtug

AndroidManifest.xml (4)

<?xml version="1.0" encoding="utf-8"?>

<manifest xmlns:android="..." package="com.my.example"

android:versionName="1.0 beta" android:versionCode="2">

<uses-configuration android:reqHardKeyboard="true"

android:reqTouchScreen="true" />

<uses-feature android:name="android.software.live_wallpaper" />

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

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

...

</manifest>

Page 71: Vk.amberfog.com gtug part1_introduction2_javaandroid_gtug

Android

• Architecture Overview

• Building Blocks

• Manifest

• System Services

• Platform versions

• Saving Application State

• NDK

• Make your code better

Page 72: Vk.amberfog.com gtug part1_introduction2_javaandroid_gtug

Android System Services

Object getApplicationContext().getSystemService(String serviceName)

serviceName value (contsants in Context)

Service Class name Description

WINDOW_SERVICE WindowManager Controls on-screen windows and their parameters

LAYOUT_INFLATER_SERVICE LayoutInflater Inflates layout resources

POWER_SERVICE PowerManager Controls power management

NOTIFICATION_SERVICE NotificationManager Status bar notifications

CONNECTIVITY_SERVICE ConnectivityManager Handling network connections

WIFI_SERVICE WifiManager Handling Wi-Fi network status

TELEPHONY_SERVICE TelephonyManager Handling phone calls states

LOCATION_SERVICE LocationManager Controls location (GPS) updates

SENSOR_SERVICE SensorManager Controls sensor

… … …

Page 73: Vk.amberfog.com gtug part1_introduction2_javaandroid_gtug

Android

• Architecture Overview

• Building Blocks

• Manifest

• System Services

• Platform versions

• Saving Application State

• NDK

• Make your code better

Page 74: Vk.amberfog.com gtug part1_introduction2_javaandroid_gtug

Android Platform Versions

• May 2009 – platform ver. 1.5

• May 2010 – platform ver. 2.2

• Six platform releases in a year (platform ver.1.1 is hard to find on real phones)

• Platforms are back-compatible

• It is good point to be compatible with dominated platforms (1.5, 1.6, 2.0.1 and 2.1)

• To use advantages of the latest platform versions, Java Reflection mechanism should be used

Page 75: Vk.amberfog.com gtug part1_introduction2_javaandroid_gtug

Android Platform Fragmentation in the World

December 2009

June 2010

Page 76: Vk.amberfog.com gtug part1_introduction2_javaandroid_gtug

Android Platform Fragmentation in Russia

• Data gathered by Flurry service in real application

• About 0.5% of 2.1 in Russia are custom ROMs

Android 1.5 ; 43,6%

Android 2.1; 33,6%

Android 1.6 ; 21,7%

Android 2.0.1 ; 0,6% Android 2.2 ; 0,5% Android 2.0 ; 0,1%

Page 77: Vk.amberfog.com gtug part1_introduction2_javaandroid_gtug

Java Reflection

• Originally used to inspect classes, interfaces, fields and methods at runtime, without knowing the names of them at compile time. It can be used for observing and/or modifying program execution at runtime

• Classes: Class, Method, Field, Constructor, etc.

// Without reflection

Foo foo = new Foo();

foo.hello();

// With reflection

Class cls = Class.forName("Foo");

Object foo = cls.newInstance();

Method method = cls.getMethod("hello", null);

method.invoke(foo, null);

Page 78: Vk.amberfog.com gtug part1_introduction2_javaandroid_gtug

Java Reflection and Android

public class ClassHolder {

private static NewClass foo;

public static void tryNewClass() {

foo = new NewClass();

}

}

try {

ClassHolder.tryNewClass();

// NewClass available

} catch (VerifyError e) {}

try {

Method methodName = ClassName.class.getMethod(...);

methodName.invoke(Object obj, Object... args);

} catch (NoSuchMethodException e) {}

try {

Field fieldName = ClassName.class.getField(...);

fieldName.getType(Object obj);

} catch (NoSuchFieldException e) {}

Page 79: Vk.amberfog.com gtug part1_introduction2_javaandroid_gtug

Java Reflection and Android (Example)

private static Field densityDpiField;

private static Field densityDpiLowResValue;

private static boolean sIsLowRes = false;

private static boolean sIsNormalRes = true;

static {

try {

densityDpiField = DisplayMetrics.class.getField("densityDpi");

densityDpiLowResValue = DisplayMetrics.class.getField("DENSITY_LOW");

} catch (NoSuchFieldException nfe) {

// Old device - no density Field

}

}

Page 80: Vk.amberfog.com gtug part1_introduction2_javaandroid_gtug

Java Reflection and Android (Example) (Cont.)

static {

if (densityDpiField != null) {

DisplayMetrics dMetrics = sContext.getResources().getDisplayMetrics();

int densityDpi = 0;

try {

densityDpi = densityDpiField.getInt(dMetrics);

sIsLowRes = (densityDpi == densityDpiLowResValue.getInt(dMetrics));

sIsNormalRes =(densityDpi==densityDpiMediumResValue.getInt(dMetrics));

} catch (Exception e) {

sIsLowRes = false;

sIsNormalRes = true;

}

}

}

Page 81: Vk.amberfog.com gtug part1_introduction2_javaandroid_gtug

Java Reflection and Android (Example) (Cont.)

public static int scaleToDensity(int dp_size) {

if (dp_size == 0 || sIsNormalRes) {

return dp_size;

}

return (int)(dp_size *

sContext.getResources().getDisplayMetrics().density + 0.5f);

}

Page 82: Vk.amberfog.com gtug part1_introduction2_javaandroid_gtug

Android

• Architecture Overview

• Building Blocks

• Manifest

• System Services

• Platform versions

• Saving Application State

• NDK

• Make your code better

Page 83: Vk.amberfog.com gtug part1_introduction2_javaandroid_gtug

Saving State of Android Application

• Shared Preferences are stored in the application private data space and can be shared only inside this Application, but between launches and versions

• Instance of SharedPreferences class should be obtained:

• To read:

• To write:

• SharedPreferences.OnSharedPreferenceChangeListener

SharedPreferences.Editor editor = mPreferences.edit();

editor.putType(String key, T value);

editor.commit();

Activity.getPreferences()

PreferenceManager.getDefaultSharedPreferences(Context ctx)

Context.getSharedPreferences(String name, int mode)

mPreferences.getType(String key, T defValue);

Page 84: Vk.amberfog.com gtug part1_introduction2_javaandroid_gtug

Backup Application Data (android.app.backup – 2.2)

• Perform backup arbitrary data to remote “cloud” storage • Easily perform backup of SharedPreferences and files • Restore the data saved to remote storage • Controlled by Android Backup Manager

– Extend class BackupAgent and override onBackup() & onRestore() OR – Extend BackupAgentHelper to backup/restore SharedPreferences and

files from internal storage – Add your agent to AndroidManifest.xml

• BackupManager.dataChanged()/requestRestore() • New bmgr tool for testing

http://developer.android.com/guide/developing/tools/bmgr.html • Full guide with examples:

http://developer.android.com/guide/topics/data/backup.html

<application android:backupAgent=".MyBackupAgent" >

Page 85: Vk.amberfog.com gtug part1_introduction2_javaandroid_gtug

Android

• Architecture Overview

• Building Blocks

• Manifest

• System Services

• Platform versions

• Saving Application State

• NDK

• Make your code better

Page 86: Vk.amberfog.com gtug part1_introduction2_javaandroid_gtug

Android NDK (Native Development Kit)

• Provides ability and tools to embed components that make use of native code in Android applications

• Supports only restricted set of native libraries:

– libc (C library) headers

– libm (math library) headers

– JNI interface headers

– libz (Zlib compression) headers

– liblog (Android logging) header

– OpenGL ES 1.1 (since 1.6) and OpenGL ES 2.0 (3D graphics libraries, since 2.0) headers

– libjnigraphics (Pixel buffer access) header (since 2.2)

– A Minimal set of headers for C++ support

• For Windows Cygwin 1.7 (or higher) is needed

Page 87: Vk.amberfog.com gtug part1_introduction2_javaandroid_gtug

Android NDK Demo

Page 88: Vk.amberfog.com gtug part1_introduction2_javaandroid_gtug

Android

• Architecture Overview

• Building Blocks

• Manifest

• System Services

• Platform versions

• Saving Application State

• NDK

• Make your code better

Page 89: Vk.amberfog.com gtug part1_introduction2_javaandroid_gtug

Designing for Performance

• Use final for constants

• Avoid enums

• Avoid float

• Use local variables for access to object fields inside loops (or more than once)

• Don’t use private scope with Inner Classes

Action Time

Add a local variable 1

Add a member variable 4

Call String.length() 5

Call empty static native method 5

Call empty static method 12

Call empty virtual method 12.5

Call empty interface method 15

Call Iterator:next() on a HashMap 165

Call put() on a HashMap 600

Inflate 1 View from XML 22,000

Inflate 1 LinearLayout containing 1 TextView

25,000

Inflate 1 LinearLayout containing 6 TextView objects

135,000

Launch an empty activity 3000,000

Page 90: Vk.amberfog.com gtug part1_introduction2_javaandroid_gtug

Designing for Responsiveness

• Application Not Responding (ANR) dialog: – No response to an input event (e.g. key press, screen

touch) within 5 seconds – A BroadcastReceiver hasn't finished executing within 10

seconds

• Quick Activity life-cycle methods (onCreate, onResume) and all other methods working on UI thread

• Use new Thread for long-time operations (i.e. network/database operations, expensive computations, bitmap resizing, etc.)

• Use ProgressBar or ProgressDialog to show “Loading…” or use splash screen when starting application

• To avoid long-time operations in BroadcastReceiver – start Service (not Activity!)

Page 91: Vk.amberfog.com gtug part1_introduction2_javaandroid_gtug

Designing for Seamlessness

• React correctly on system events (i.e. phone call) • onSaveInstanceState/onResumeInstanceState • onPause/onResume • TelephonyManager, etc.

• Share data using ContentProvider • Use NotificationManager and Notifications from background

processes (Service, BroadcastReceiver) • Don’t overload a single Activity screen – use several Activities for

correct dealing with history and Android “backstack” model • Use Threads for long-time operations to avoid ANR • Remember about multiple screen resolutions and multiple Android

platform versions • Assume the Network is slow (change speed in Eclipse DDMS for

Emulator) • Don’t assume Touchscreen or Keyboard • Remember about battery life

Page 92: Vk.amberfog.com gtug part1_introduction2_javaandroid_gtug

Partners

Page 93: Vk.amberfog.com gtug part1_introduction2_javaandroid_gtug

Contacts

Dmitry Lukashev

http://ru.linkedin.com/in/dmitrylukashev

[email protected]

Blog - http://android.amberfog.com/

Alexey Golubev

http://ru.linkedin.com/in/golubevalexey

[email protected]

Page 94: Vk.amberfog.com gtug part1_introduction2_javaandroid_gtug

Future reading

• http://developer.android.com/guide/index.html

• http://developer.android.com/resources/index.html

• Soft, weak, phantom references: http://www.ibm.com/developerworks/library/j-refs/ http://www.ibm.com/developerworks/java/library/j-jtp11225/index.html http://www.ibm.com/developerworks/java/library/j-jtp01246.html

• JVM specification: http://java.sun.com/docs/books/jvms/second_edition/html/VMSpecTOC.doc.html

• The Java Memory Model: http://www.cs.umd.edu/~pugh/java/memoryModel/

• Dalvik VM: http://sites.google.com/site/io/dalvik-vm-internals

• Reflection: http://java.sun.com/docs/books/tutorial/reflect/TOC.html http://tutorials.jenkov.com/java-reflection/index.html

Page 95: Vk.amberfog.com gtug part1_introduction2_javaandroid_gtug

Thank You!

Questions?