Transcript
Page 1: Rounds tips & tricks

The “Rounds Project”

Growing from thousands to millions Tips and tricks from the battlefield

Page 2: Rounds tips & tricks

What is Rounds?

Page 3: Rounds tips & tricks

What is Rounds?

Page 4: Rounds tips & tricks

•Fun, eyecandy, social, viral, useful Thank you Product Team!

•Scalable, fast, reliable, predictable backend Thank you Server Team!

•Great Client sideThat’s us! The Rounds Android TeamYohay, Berry, Shay, Vadim and

growing...

The Key for a Great App

Page 5: Rounds tips & tricks

•Supporting as many devices, OS versions and languages as possible

•Robust, Crash-free app

•Responsive UI, using latest guidelines

•Surprise & Delight the user

Great Client Side

Page 6: Rounds tips & tricks

Android 4.03 and aboveOnly about 8% of users use

Froyo, Gingerbread & below

so...we only support 4.03 and above (release quicker, use newer features).

Page 7: Rounds tips & tricks

Support 24 languages

For common iOS & Android translations

Page 8: Rounds tips & tricks

Support 7130 devices

QA? Code Reviews In house test most popular devices Applause for testing all over the world TestFairy for usability videos

Page 9: Rounds tips & tricks

Support 7130 devices

Release:Start with 20% rolloutCrashlytics for amazing crash analyticsIncrease after a few days

Page 10: Rounds tips & tricks

Responsive UI ?

•Used new Thread() every time Oh no! Don’t do that!!

•Used synchronized on UI thread Argh! Blocked it and got nasty ANRs!

•Fetched again the same info from server

Users had to wait…

Page 11: Rounds tips & tricks

Use a ThreadPool!•Changed every call of

new Thread(someRunable).start();

•ToRoundsExecutor.get().execute(someRunable);

•And the resultWith a few hours workAmazing improvement in performance!

Page 12: Rounds tips & tricks

public class RoundsExecutor {

private static ExecutorService sPool =

Executors.newCachedThreadPool();

public static ExecutorService get() {return sPool;

}

private RoundsExecutor(){ }}

Page 13: Rounds tips & tricks

•synchronized, do you really need it? avoid it completely on UI thread if yes… code review anyway

•pay attention where you are running.if it is a callback then… who is calling?

Parallel Threads Beware

Page 14: Rounds tips & tricks

IntentService

•Creates a single background thread •Will process only one task at a time •Send the service an intent with what to do

Use LocalBroadcastManager to broadcast event with result

Use a BroadcastReceiver to handle result on UI thread

Page 15: Rounds tips & tricks

Managing Data

Model View

Controller

Page 16: Rounds tips & tricks

Managing Data

ModelPersist Locally

Notify when changed

Servers

UI Widgets

Activity orFragment

Fetch from Server

Page 17: Rounds tips & tricks

Managing Data

ModelPersist Locally

Notify when changed

Servers

UI Widgets

Activity orFragment

Fetch from Server

Persist in Server

Page 18: Rounds tips & tricks

Managing Data

ModelPersist Locally

Notify when changed

Servers

UI Widgets

Activity orFragment

Fetch from Server

GCM / XMPP Push

Persist in Server

Page 19: Rounds tips & tricks

Managing Data

ModelPersist Locally

Notify when changed

Servers

UI Widgets

Activity orFragment

Fetch from Server

GCM / XMPP Push

Persist in Server

Page 20: Rounds tips & tricks

Persisting Data

SharedPreferences for simple dataSQLLite for more complicated dataUniversalImageLoader for images

Page 21: Rounds tips & tricks

We wanted an IntentService that would•reschedule tasks that failed •schedule tasks for later•stay alive until we asked it to stop

github.com/berryve/rounds-android-goodies

FlexibleIntentService

Page 22: Rounds tips & tricks

•Any component can broadcast events using LocalBroadcastManager

•Any component can declare events it is interested in and how to handle

thempublic interface RoundsBroadcastListener {

public String [] getInterests();public void

handleRoundsEvent(String action, Bundle extras);}

Event Pipeline

Page 23: Rounds tips & tricks

We developed our handler mHandler = new RoundsEventHandler(context, roundsBroadcastListener)

Base classes that implement the listenerAnd use our handlerRoundsActivityBase RoundsFragmentBase

Event Pipeline

Page 24: Rounds tips & tricks

Start listening at onResume()mHandler.registerReceivers();

Stop listening at onPause()mHandler.unregisterReceivers();

github.com/berryve/rounds-android-goodies

Event Pipeline

Page 25: Rounds tips & tricks

Surprise & Delight

Page 26: Rounds tips & tricks

yeti_eyes.xml<animation-list android:oneshot="false" > <item android:drawable="@drawable/yeti_eyes_1" android:duration="3000"/> <item android:drawable="@drawable/yeti_eyes_2" android:duration="50"/> … etc … </animation-list>

How to make a Yeti Blink

Page 27: Rounds tips & tricks

How to make a Yeti Blink•create an animation-list xml resourcethat references frame by frame eye images

•Variate duration values To mimic live object Random can be better!

•On the ImageView you want to animate:

yetiEyes.setBackgroundResource(R.drawable.yeti_eyes)

Page 28: Rounds tips & tricks

How to make a Yeti Blink

•To start the animation on yetiEyes ImageView

AnimationDrawable eyesAnimation = (AnimationDrawable)yetiEyes.getBackground();

eyesAnimation.start();

Page 29: Rounds tips & tricks
Page 30: Rounds tips & tricks

Summary

•Make great product that people want to use•Keep basic design principles in mind•Use tools & services for crash free app•Add Fun Surprises & Delights•Can’t get it perfect the first time•Keep learning and improve as you go


Top Related