the rounds project: growing from thousands to millions - berry ventura & yoahy barsky, rounds

31
The “Rounds Project” Growing from thousands to millions Tips and tricks from the battlefield

Upload: droidcontlv

Post on 15-Aug-2015

75 views

Category:

Technology


1 download

TRANSCRIPT

The “Rounds Project” Growing from thousands to millions

Tips and tricks from the battlefield

What is Rounds?

What is Rounds?

•Fun, eyecandy, social, viral, useful

Thank you Product Team!

•Scalable, fast, reliable, predictable backend

Thank you Server Team!

•Great Client side

That’s us! The Rounds Android Team

Yohay, Berry, Shay, Vadim and growing...

The Key for a Great App

•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

Android 4.03 and above

Only about 8% of users use

Froyo, Gingerbread & below

so...

we only support 4.03 and above

(release quicker, use newer features).

Support 24 languages

For common iOS & Android translations

Support 7130 devices

QA?

Code Reviews

In house test most popular devices

Applause for testing all over the world

TestFairy for usability videos

Support 7130 devices

Release:

Start with 20% rollout

Crashlytics for amazing crash analytics

Increase after a few days

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…

Use a ThreadPool!

•Changed every call of

new Thread(someRunable).start();

•To

RoundsExecutor.get().execute(someRunable);

•And the result

With a few hours work

Amazing improvement in performance!

public class RoundsExecutor {

private static ExecutorService sPool =

Executors.newCachedThreadPool();

public static ExecutorService get() {

return sPool;

}

private RoundsExecutor(){ }

}

•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

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

Managing Data

Model View

Controller

Managing Data

Model Persist Locally

Notify when changed

Servers

UI

Widgets

Activity or

Fragment

Fetch from Server

Managing Data

Model Persist Locally

Notify when changed

Servers

UI

Widgets

Activity or

Fragment

Fetch from Server Persist in Server

Managing Data

Model Persist Locally

Notify when changed

Servers

UI

Widgets

Activity or

Fragment

Fetch from Server GCM / XMPP Push Persist in Server

Managing Data

Model Persist Locally

Notify when changed

Servers

UI

Widgets

Activity or

Fragment

Fetch from Server GCM / XMPP Push Persist in Server

Persisting Data

We use

SharedPreferences for simple data

SQLLite for more complicated data

UniversalImageLoader for images

We wanted an IntentService that would

•reschedule tasks that failed

•schedule tasks for later

•stay alive until we asked it to stop

github.com/rounds/rounds-android-goodies

FlexibleIntentService

•Any component can broadcast events

using LocalBroadcastManager

•Any component can declare events

it is interested in and how to handle them

public interface RoundsBroadcastListener {

public String [] getInterests();

public void handleRoundsEvent(String

action, Bundle extras);

}

Event Pipeline

We developed our handler

mHandler =

new RoundsEventHandler(context,

roundsBroadcastListener)

Base classes that implement the listener

And use our handler

RoundsActivityBase

RoundsFragmentBase

Event Pipeline

Start listening at onResume()

mHandler.registerReceivers();

Stop listening at onPause()

mHandler.unregisterReceivers();

github.com/rounds/rounds-android-goodies

Event Pipeline

Surprise & Delight

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

How to make a Yeti Blink

•Create an animation-list xml resource

that lists frame by frame images

•To mimic a live object use

Random duration values

•On the ImageView you want to animate:

yetiEyes.setBackgroundResource(

R.drawable.yeti_eyes)

How to make a Yeti Blink

Animate yetiEyes ImageView with

AnimationDrawable yetiEyesAnimation =

(AnimationDrawable) yetiEyes.getBackground();

yetiEyesAnimation.start();

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