SlideShare a Scribd company logo
1 of 55
Download to read offline
Painless Persistence
on Android
Christian Melchior
@chrmelchior
cm@realm.io
Why design for offline?
• A better USER EXPERIENCE!
• You always have something to show the user
• Reduce network requests and data transferred
• Saves battery
Designing for Offline
Offline architecture
MVVM
MVP
MVC
VIPER
Flux
Clean
Architecture
?
?
? ?
?
?
?
?
?
?
?
?
??
??
They all have a model
MVVM
MVP
MVC
VIPER
Flux
Clean
Architecture
ModelView
getData()
data
You’re doing it wrong!
@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);



// Setup initial views

setContentView(R.layout.activity_main);



// Load data and show it

Retrofit retrofit = new Retrofit.Builder()

.addConverterFactory(JacksonConverterFactory.create())

.baseUrl("http://api.nytimes.com/")

.build();



service = retrofit.create(NYTimesService.class);

service.topStories("home", "my-key").enqueue(new Callback<NYTimesResponse<List<NYTimesStory>>>() {

@Override

public void onResponse(Response<NYTimesResponse<List<NYTimesStory>>> response, Retrofit retrofit) {

showList(response);

}



@Override

public void onFailure(Throwable t) {

showError(t);

}

});

}

You’re doing it right!
@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);



// Setup initial views

setContentView(R.layout.activity_main);



// Load data and show it

Model model = ((MyApplication) getApplicationContext()).getModel();

model.getTopStories(new Observer() {

@Override

public void update(Observable observable, NYTimesResponse<List<NYTimesStory>> data) {

showList(data);

}

});

}

Encapsulate data
ModelView
Cache
Database
Network
Repository pattern
ModelView
Cache
Database
Network
Repository
Business rules
Creating/
fetching data
Repository pattern
• Repository only has CRUD methods:
• Create()
• Read()
• Update()
• Delete()
• Model and Repository can be tested separately.
Designing for offline
Repository… DatastoregetData()
Observable<Data>()
Network
Update?
Save
Designing for offline
• Encapsulate data access
• The datastore is single-source-of-truth
• Everything is asynchronous
• Observer pattern
• RxJava
• EventBus
• Testing becomes easier
Persisting data
File system
• Define hierarchy using folders
• No help from the framework
• Use cases: Images, JSON blobs
File system
// App internal files

context.getFilesDir();

context.getCacheDir();



// App external files

context.getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS);

context.getExternalCacheDir();



// SD Card

Environment.getExternalStorageDirectory();

SharedPreferences
• Key-value store
• Simple XML file
• Use cases: Settings, Key/Value data
• Simple API’s and easy to use
SharedPreferences
// Save data

SharedPreferences pref = getPreferences(MODE_PRIVATE);

SharedPreferences.Editor editor = pref.edit();

editor.putBoolean("key", true);

editor.commit();

// Read data
boolean data = pref.getBoolean("key", false);

Databases
• Use cases: Structured data sets
• Advanced composing and query capabilities
• Complex API’s
SQLite vs. the World
• SQLite (Relational)
• Realm (Object store)
• Firebase (Document oriented)
• Couchbase Lite (Document oriented)
• Parse (Document oriented)
The Relational Model
Relational data
Relational data
BCNF
Relational data
Relational data
m:n?
Relational data
Relational data
SELECT owner.name, dog.name, city.name


FROM owner

INNER JOIN dog ON owner.dog_id = dog.id

INNER JOIN city ON owner.city_id = city.id

WHERE owner.name = 'Frank'
SQLite
String query = "SELECT " + Owner.NAME + ", " + Dog.NAME + ", " + City.NAME


+ " FROM " + Owner.TABLE_NAME

+ " INNER JOIN " + Dog.TABLE_NAME + " ON " + Owner.DOG_ID + " = " + Dog.ID

+ " INNER JOIN " + City.TABLE_NAME + " ON " + Owner.CITY_ID + " = " + City.ID

+ " WHERE " + Owner.NAME = "'" + escape(queryName) + "'";

SQLite
“Lets use an ORM”
Abstract the problem away
–Joel Spolsky
“All non-trivial abstractions, to some degree,
are leaky.”
Solved problem?
• ActiveRecord
• Androrm
• Blurb
• Cupboard
• DBFlow
• DBQuery
• DBTools
• EasyliteOrm
• GreenDAO
• Ollie
• Orman
• OrmLite
• Persistence
• RushORM
• Shillelagh
• Sprinkles
• SquiDB
• SugarORM
Realm?
Object Store
A
B C
D E F
G
VS
x
z
y
x y z
SELECT table1.x, table2.y, table3.z

FROM table1

INNER JOIN table2 ON table1.table2_id = table1.id

INNER JOIN table3 ON table1.table3_id = table3.id

References in SQL
A
B C
D E F
G
Realm.getA().getC().getF()
Object Store references
Zero-copy
	
  Person	
  {	
  
• name	
  =	
  Tommy	
  
• age	
  =	
  8	
  
• dog	
  =	
  {	
  
• name	
  =	
  Lassie	
  	
  
	
  	
  	
  }	
  
	
  }
	
  Person	
  {	
  
• name	
  =	
  Tommy	
  
• age	
  =	
  8	
  
• dog	
  =	
  {	
  
• name	
  =	
  Lassie	
  	
  
	
  	
  	
  }	
  
	
  }
	
  Person	
  {	
  
• name	
  =	
  Tommy	
  
• age	
  =	
  8	
  
• dog	
  =	
  {	
  
• name	
  =	
  Lassie	
  	
  
	
  	
  	
  }	
  
	
  }
	
  PersonProxy	
  {	
  
• name	
  
• age	
  
• dog	
  	
  
	
  }
	
  PersonProxy	
  {	
  
• name	
  
• age	
  
• dog	
  	
  
	
  }
	
  Person	
  {	
  
• name	
  =	
  Tommy	
  
• age	
  =	
  8	
  
• dog	
  =	
  {	
  
• name	
  =	
  Lassie	
  	
  
	
  	
  	
  }	
  
	
  }
Realm
ORM Realm
SQLite
Benchmarks
http://static.realm.io/downloads/java/android-benchmark.zip
1.09%
2.26%
3.79%
4.55%
22.85%
13.37%
1% 1% 1% 1% 1% 1%
0%
5%
10%
15%
20%
25%
BatchWrite% SimpleWrite% SimpleQuery% FullScan% Sum% Count%
Speedup&vs.&SQLite&
Tests&/&1000&objects&
Realm%
SQLite%
SQLite vs. Realm
• Part of Android
• Relational data model
• Based on SQL
• Public Domain
• One of the most tested pieces of software
• Need to map between SQL and Java
objects (manually or ORM).
• Foreign collections is an unsolvable
problem.
• Complex API’s
• Objects all the way down
• Zero copy architecture
• Cross-platform
• Supports encryption out of the box
• Open source*
• Custom query language
• Will add ~2500 methods + 800 kB of native
code.
• Still in beta
“Talk is cheap. Show
me the code.”
–Linus Torvalds
Adding Realm
// ./build.gradle

buildscript {

repositories {

jcenter()

}

dependencies {

classpath 'com.android.tools.build:gradle:2.0.0-alpha1'

classpath 'io.realm:realm-gradle-plugin:0.86.0'

}

}

// ./app/build.gradle

apply plugin: 'com.android.application'

apply plugin: 'realm'

Models and Schema
public class Person extends RealmObject {

private String name;

private int age;

private Dog dog;

private RealmList<Cat> cats;
// Autogenerated getters/setters

}
public class Cat extends RealmObject {

private String name;

// Autogenerated getters/setters

}
public class Dog extends RealmObject {

private String name;

// Autogenerated getters/setters

}
Getting an Realm instance
// Default configuration. Schema is automatically detected
RealmConfiguration config = new RealmConfiguration.Builder(context).build();

Realm.setDefaultConfiguration(config);

Realm realm = Realm.getDefaultInstance();



Create objects - Realm
// Create and set persisted objects

realm.beginTransaction();

Person person = realm.createObject(Person.class);

person.setName("Young Person");

person.setAge(14);

realm.commitTransaction();

// Copy java objects

Person person = new Person();

person.setName("Young Person");

person.setAge(14);



realm.beginTransaction();

realm.copyToRealm(person);

realm.commitTransaction();

• Extend RealmObject
• POJO: Plain Old Java Object
Transactions - Realm
// Simple writes

realm.beginTransaction();

// ...

realm.commitTransaction();

// Automatically handle begin/commit/cancel

realm.executeTransaction(new Realm.Transaction() {

@Override

public void execute(Realm realm) {

// ...

}

});

Queries
RealmResults<Person> results = realm.where(Person.class)
.equalTo("age", 99)
.findAll();

RealmResults<Person> results = realm.where(Person.class)
.equalTo("cats.name", “Tiger")
.findAll();

RealmResults<Person> results = realm.where(Person.class)
.beginsWith("name", “John")
.findAllAsync();

results.addChangeListener(new RealmChangeListener() {

@Override

public void onChange() {

showResults(results);

}

});

• Fluent queries
• Semi-typesafe
• Easy async
• Always up-to-date
Network data
// Use Retrofit to parse objects

Retrofit retrofit = new Retrofit.Builder()

.addConverterFactory(JacksonConverterFactory.create())

.baseUrl("http://api.nytimes.com/")

.build();



MyRestApi service = retrofit.create(MyRestApi.class);

final Data data = service.getData();



// Copy all data into Realm

realm.executeTransaction(new Realm.Transaction() {

@Override

public void execute(Realm realm) {

realm.copyToRealmOrUpdate(data);

}

});

RxJava (Realm)
Observable<Realm> observableRealm = realm.asObservable();

Observable<RealmResults<Person>> results = realm.where(Person.class)
.beginsWith("name", “John")
.findAllAsync()
.asObservable();

Observable<Person> results = realm.where(Person.class).findFirst().asObservable();

Observable<RealmQuery> results = realm.where(Person.class).asObservable();

Example
https://github.com/realm/realm-java/tree/cm/offline-
newsreader/examples/newsreaderExample
Take aways
• Not everyone is on Wifi or 4G networks
• Encapsulate data access
• Designing for offline gives a a better USER
EXPERIENCE!
Resources
• Repository Pattern: http://martinfowler.com/eaaCatalog/
repository.html
• Design for offline: https://plus.google.com/
+AndroidDevelopers/posts/3C4GPowmWLb
• MVP example: https://www.code-labs.io/codelabs/
android-testing/#0
• Optimizing network requests: https://www.youtube.com/
playlist?list=PLWz5rJ2EKKc9CBxr3BVjPTPoDPLdPIFCE
• Realm : https://realm.io/docs/java/latest/
Questions?
@chrmelchior
cm@realm.io
We are hiring
https://realm.io/jobs/

More Related Content

What's hot

Useful and Practical Functionalities in Realm
Useful and Practical Functionalities in RealmUseful and Practical Functionalities in Realm
Useful and Practical Functionalities in RealmYusuke Kita
 
Akka and the Zen of Reactive System Design
Akka and the Zen of Reactive System DesignAkka and the Zen of Reactive System Design
Akka and the Zen of Reactive System DesignLightbend
 
Zepto.js, a jQuery-compatible mobile JavaScript framework in 2K
Zepto.js, a jQuery-compatible mobile JavaScript framework in 2KZepto.js, a jQuery-compatible mobile JavaScript framework in 2K
Zepto.js, a jQuery-compatible mobile JavaScript framework in 2KThomas Fuchs
 
Crafting Evolvable Api Responses
Crafting Evolvable Api ResponsesCrafting Evolvable Api Responses
Crafting Evolvable Api Responsesdarrelmiller71
 
ElasticSearch for .NET Developers
ElasticSearch for .NET DevelopersElasticSearch for .NET Developers
ElasticSearch for .NET DevelopersBen van Mol
 
Building an aws sdk for Perl - Granada Perl Workshop 2014
Building an aws sdk for Perl - Granada Perl Workshop 2014Building an aws sdk for Perl - Granada Perl Workshop 2014
Building an aws sdk for Perl - Granada Perl Workshop 2014Jose Luis Martínez
 
Paws - Perl AWS SDK Update - November 2015
Paws - Perl AWS SDK Update - November 2015Paws - Perl AWS SDK Update - November 2015
Paws - Perl AWS SDK Update - November 2015Jose Luis Martínez
 
Кирилл Безпалый, .NET Developer, Ciklum
Кирилл Безпалый, .NET Developer, CiklumКирилл Безпалый, .NET Developer, Ciklum
Кирилл Безпалый, .NET Developer, CiklumAlina Vilk
 
"ClojureScript journey: from little script, to CLI program, to AWS Lambda fun...
"ClojureScript journey: from little script, to CLI program, to AWS Lambda fun..."ClojureScript journey: from little script, to CLI program, to AWS Lambda fun...
"ClojureScript journey: from little script, to CLI program, to AWS Lambda fun...Julia Cherniak
 
Restful App Engine
Restful App EngineRestful App Engine
Restful App EngineRyan Morlok
 
Intro to React
Intro to ReactIntro to React
Intro to ReactTroy Miles
 
Getting the most out of Java [Nordic Coding-2010]
Getting the most out of Java [Nordic Coding-2010]Getting the most out of Java [Nordic Coding-2010]
Getting the most out of Java [Nordic Coding-2010]Sven Efftinge
 
Scala.js for large and complex frontend apps
Scala.js for large and complex frontend appsScala.js for large and complex frontend apps
Scala.js for large and complex frontend appsOtto Chrons
 
Fast C++ Web Servers
Fast C++ Web ServersFast C++ Web Servers
Fast C++ Web ServersTroy Miles
 
Paws: A Perl AWS SDK - YAPC Europe 2015
Paws: A Perl AWS SDK - YAPC Europe 2015Paws: A Perl AWS SDK - YAPC Europe 2015
Paws: A Perl AWS SDK - YAPC Europe 2015CAPSiDE
 

What's hot (20)

Useful and Practical Functionalities in Realm
Useful and Practical Functionalities in RealmUseful and Practical Functionalities in Realm
Useful and Practical Functionalities in Realm
 
Akka and the Zen of Reactive System Design
Akka and the Zen of Reactive System DesignAkka and the Zen of Reactive System Design
Akka and the Zen of Reactive System Design
 
Zepto.js, a jQuery-compatible mobile JavaScript framework in 2K
Zepto.js, a jQuery-compatible mobile JavaScript framework in 2KZepto.js, a jQuery-compatible mobile JavaScript framework in 2K
Zepto.js, a jQuery-compatible mobile JavaScript framework in 2K
 
Crafting Evolvable Api Responses
Crafting Evolvable Api ResponsesCrafting Evolvable Api Responses
Crafting Evolvable Api Responses
 
ElasticSearch for .NET Developers
ElasticSearch for .NET DevelopersElasticSearch for .NET Developers
ElasticSearch for .NET Developers
 
ES6: The Awesome Parts
ES6: The Awesome PartsES6: The Awesome Parts
ES6: The Awesome Parts
 
Building an aws sdk for Perl - Granada Perl Workshop 2014
Building an aws sdk for Perl - Granada Perl Workshop 2014Building an aws sdk for Perl - Granada Perl Workshop 2014
Building an aws sdk for Perl - Granada Perl Workshop 2014
 
Paws - Perl AWS SDK Update - November 2015
Paws - Perl AWS SDK Update - November 2015Paws - Perl AWS SDK Update - November 2015
Paws - Perl AWS SDK Update - November 2015
 
Paws - A Perl AWS SDK
Paws - A Perl AWS SDKPaws - A Perl AWS SDK
Paws - A Perl AWS SDK
 
Кирилл Безпалый, .NET Developer, Ciklum
Кирилл Безпалый, .NET Developer, CiklumКирилл Безпалый, .NET Developer, Ciklum
Кирилл Безпалый, .NET Developer, Ciklum
 
"ClojureScript journey: from little script, to CLI program, to AWS Lambda fun...
"ClojureScript journey: from little script, to CLI program, to AWS Lambda fun..."ClojureScript journey: from little script, to CLI program, to AWS Lambda fun...
"ClojureScript journey: from little script, to CLI program, to AWS Lambda fun...
 
Realm database
Realm databaseRealm database
Realm database
 
Restful App Engine
Restful App EngineRestful App Engine
Restful App Engine
 
Intro to React
Intro to ReactIntro to React
Intro to React
 
Requery overview
Requery overviewRequery overview
Requery overview
 
Getting the most out of Java [Nordic Coding-2010]
Getting the most out of Java [Nordic Coding-2010]Getting the most out of Java [Nordic Coding-2010]
Getting the most out of Java [Nordic Coding-2010]
 
Scala.js for large and complex frontend apps
Scala.js for large and complex frontend appsScala.js for large and complex frontend apps
Scala.js for large and complex frontend apps
 
Spring data requery
Spring data requerySpring data requery
Spring data requery
 
Fast C++ Web Servers
Fast C++ Web ServersFast C++ Web Servers
Fast C++ Web Servers
 
Paws: A Perl AWS SDK - YAPC Europe 2015
Paws: A Perl AWS SDK - YAPC Europe 2015Paws: A Perl AWS SDK - YAPC Europe 2015
Paws: A Perl AWS SDK - YAPC Europe 2015
 

Viewers also liked

Android custom listview
Android custom listviewAndroid custom listview
Android custom listviewparmistech
 
Android Architecture MVP Pattern
Android Architecture MVP Pattern Android Architecture MVP Pattern
Android Architecture MVP Pattern Jeff Potter
 
Persistence in Android
Persistence in AndroidPersistence in Android
Persistence in Androidma-polimi
 
Open Ldap Integration and Configuration with Lifray 6.2
Open Ldap Integration and Configuration with Lifray 6.2Open Ldap Integration and Configuration with Lifray 6.2
Open Ldap Integration and Configuration with Lifray 6.2Vinaykumar Hebballi
 
Android Life Cycle
Android Life CycleAndroid Life Cycle
Android Life Cyclemssaman
 
Android development - ListView & Adapter
Android development - ListView & AdapterAndroid development - ListView & Adapter
Android development - ListView & AdapterLope Emano
 
Android life cycle
Android life cycleAndroid life cycle
Android life cycle瑋琮 林
 
Realm: 초고속 데이터베이스
Realm: 초고속 데이터베이스Realm: 초고속 데이터베이스
Realm: 초고속 데이터베이스Leonardo YongUk Kim
 
Android lifecycle
Android lifecycleAndroid lifecycle
Android lifecycleKumar
 
Introduction to Listview in Android
Introduction to Listview in AndroidIntroduction to Listview in Android
Introduction to Listview in Androidtechnoguff
 
ListView and Custom ListView on Android Development [Thai]
ListView and Custom ListView on Android Development [Thai]ListView and Custom ListView on Android Development [Thai]
ListView and Custom ListView on Android Development [Thai]Somkiat Khitwongwattana
 
Android activity lifecycle
Android activity lifecycleAndroid activity lifecycle
Android activity lifecycleSoham Patel
 
Realm: Building a mobile database
Realm: Building a mobile databaseRealm: Building a mobile database
Realm: Building a mobile databaseChristian Melchior
 
Railway Oriented Programming
Railway Oriented ProgrammingRailway Oriented Programming
Railway Oriented ProgrammingScott Wlaschin
 

Viewers also liked (20)

Json vs Gson vs Jackson
Json vs Gson vs JacksonJson vs Gson vs Jackson
Json vs Gson vs Jackson
 
Product director
Product directorProduct director
Product director
 
Android custom listview
Android custom listviewAndroid custom listview
Android custom listview
 
Android Data Persistence
Android Data PersistenceAndroid Data Persistence
Android Data Persistence
 
Android Architecture MVP Pattern
Android Architecture MVP Pattern Android Architecture MVP Pattern
Android Architecture MVP Pattern
 
Persistence in Android
Persistence in AndroidPersistence in Android
Persistence in Android
 
Android Custom view
Android Custom view Android Custom view
Android Custom view
 
Google android Activity lifecycle
Google android Activity lifecycle Google android Activity lifecycle
Google android Activity lifecycle
 
Open Ldap Integration and Configuration with Lifray 6.2
Open Ldap Integration and Configuration with Lifray 6.2Open Ldap Integration and Configuration with Lifray 6.2
Open Ldap Integration and Configuration with Lifray 6.2
 
Android Life Cycle
Android Life CycleAndroid Life Cycle
Android Life Cycle
 
Android development - ListView & Adapter
Android development - ListView & AdapterAndroid development - ListView & Adapter
Android development - ListView & Adapter
 
Android life cycle
Android life cycleAndroid life cycle
Android life cycle
 
Realm: 초고속 데이터베이스
Realm: 초고속 데이터베이스Realm: 초고속 데이터베이스
Realm: 초고속 데이터베이스
 
Android lifecycle
Android lifecycleAndroid lifecycle
Android lifecycle
 
Introduction to Listview in Android
Introduction to Listview in AndroidIntroduction to Listview in Android
Introduction to Listview in Android
 
ListView and Custom ListView on Android Development [Thai]
ListView and Custom ListView on Android Development [Thai]ListView and Custom ListView on Android Development [Thai]
ListView and Custom ListView on Android Development [Thai]
 
Android activity lifecycle
Android activity lifecycleAndroid activity lifecycle
Android activity lifecycle
 
Realm: Building a mobile database
Realm: Building a mobile databaseRealm: Building a mobile database
Realm: Building a mobile database
 
Effective Android UI - English
Effective Android UI - EnglishEffective Android UI - English
Effective Android UI - English
 
Railway Oriented Programming
Railway Oriented ProgrammingRailway Oriented Programming
Railway Oriented Programming
 

Similar to Painless Persistence in a Disconnected World

Art of Javascript
Art of JavascriptArt of Javascript
Art of JavascriptTarek Yehia
 
[Coscup 2012] JavascriptMVC
[Coscup 2012] JavascriptMVC[Coscup 2012] JavascriptMVC
[Coscup 2012] JavascriptMVCAlive Kuo
 
Amazon Web Services for PHP Developers
Amazon Web Services for PHP DevelopersAmazon Web Services for PHP Developers
Amazon Web Services for PHP DevelopersJeremy Lindblom
 
jQuery Makes Writing JavaScript Fun Again (for HTML5 User Group)
jQuery Makes Writing JavaScript Fun Again (for HTML5 User Group)jQuery Makes Writing JavaScript Fun Again (for HTML5 User Group)
jQuery Makes Writing JavaScript Fun Again (for HTML5 User Group)Doris Chen
 
SharePoint and jQuery Essentials
SharePoint and jQuery EssentialsSharePoint and jQuery Essentials
SharePoint and jQuery EssentialsMark Rackley
 
[JCConf 2020] 用 Kotlin 跨入 Serverless 世代
[JCConf 2020] 用 Kotlin 跨入 Serverless 世代[JCConf 2020] 用 Kotlin 跨入 Serverless 世代
[JCConf 2020] 用 Kotlin 跨入 Serverless 世代Shengyou Fan
 
The Magic Revealed: Four Real-World Examples of Using the Client Object Model...
The Magic Revealed: Four Real-World Examples of Using the Client Object Model...The Magic Revealed: Four Real-World Examples of Using the Client Object Model...
The Magic Revealed: Four Real-World Examples of Using the Client Object Model...SPTechCon
 
WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...Fabio Franzini
 
JRuby + Rails = Awesome Java Web Framework at Jfokus 2011
JRuby + Rails = Awesome Java Web Framework at Jfokus 2011JRuby + Rails = Awesome Java Web Framework at Jfokus 2011
JRuby + Rails = Awesome Java Web Framework at Jfokus 2011Nick Sieger
 
前端MVC之BackboneJS
前端MVC之BackboneJS前端MVC之BackboneJS
前端MVC之BackboneJSZhang Xiaoxue
 
Full stack development with node and NoSQL - All Things Open - October 2017
Full stack development with node and NoSQL - All Things Open - October 2017Full stack development with node and NoSQL - All Things Open - October 2017
Full stack development with node and NoSQL - All Things Open - October 2017Matthew Groves
 
Full Stack Development with Node.js and NoSQL
Full Stack Development with Node.js and NoSQLFull Stack Development with Node.js and NoSQL
Full Stack Development with Node.js and NoSQLAll Things Open
 
fuser interface-development-using-jquery
fuser interface-development-using-jqueryfuser interface-development-using-jquery
fuser interface-development-using-jqueryKostas Mavridis
 
Swift Micro-services and AWS Technologies
Swift Micro-services and AWS TechnologiesSwift Micro-services and AWS Technologies
Swift Micro-services and AWS TechnologiesSimonPilkington8
 
Understanding backbonejs
Understanding backbonejsUnderstanding backbonejs
Understanding backbonejsNick Lee
 
Scalable web application architecture
Scalable web application architectureScalable web application architecture
Scalable web application architecturepostrational
 

Similar to Painless Persistence in a Disconnected World (20)

Art of Javascript
Art of JavascriptArt of Javascript
Art of Javascript
 
[Coscup 2012] JavascriptMVC
[Coscup 2012] JavascriptMVC[Coscup 2012] JavascriptMVC
[Coscup 2012] JavascriptMVC
 
Amazon Web Services for PHP Developers
Amazon Web Services for PHP DevelopersAmazon Web Services for PHP Developers
Amazon Web Services for PHP Developers
 
jQuery Makes Writing JavaScript Fun Again (for HTML5 User Group)
jQuery Makes Writing JavaScript Fun Again (for HTML5 User Group)jQuery Makes Writing JavaScript Fun Again (for HTML5 User Group)
jQuery Makes Writing JavaScript Fun Again (for HTML5 User Group)
 
Full Stack Scala
Full Stack ScalaFull Stack Scala
Full Stack Scala
 
Real World MVC
Real World MVCReal World MVC
Real World MVC
 
Linq
LinqLinq
Linq
 
SharePoint and jQuery Essentials
SharePoint and jQuery EssentialsSharePoint and jQuery Essentials
SharePoint and jQuery Essentials
 
[JCConf 2020] 用 Kotlin 跨入 Serverless 世代
[JCConf 2020] 用 Kotlin 跨入 Serverless 世代[JCConf 2020] 用 Kotlin 跨入 Serverless 世代
[JCConf 2020] 用 Kotlin 跨入 Serverless 世代
 
The Magic Revealed: Four Real-World Examples of Using the Client Object Model...
The Magic Revealed: Four Real-World Examples of Using the Client Object Model...The Magic Revealed: Four Real-World Examples of Using the Client Object Model...
The Magic Revealed: Four Real-World Examples of Using the Client Object Model...
 
WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...
 
JRuby + Rails = Awesome Java Web Framework at Jfokus 2011
JRuby + Rails = Awesome Java Web Framework at Jfokus 2011JRuby + Rails = Awesome Java Web Framework at Jfokus 2011
JRuby + Rails = Awesome Java Web Framework at Jfokus 2011
 
前端MVC之BackboneJS
前端MVC之BackboneJS前端MVC之BackboneJS
前端MVC之BackboneJS
 
Full stack development with node and NoSQL - All Things Open - October 2017
Full stack development with node and NoSQL - All Things Open - October 2017Full stack development with node and NoSQL - All Things Open - October 2017
Full stack development with node and NoSQL - All Things Open - October 2017
 
Full Stack Development with Node.js and NoSQL
Full Stack Development with Node.js and NoSQLFull Stack Development with Node.js and NoSQL
Full Stack Development with Node.js and NoSQL
 
fuser interface-development-using-jquery
fuser interface-development-using-jqueryfuser interface-development-using-jquery
fuser interface-development-using-jquery
 
ERRest and Dojo
ERRest and DojoERRest and Dojo
ERRest and Dojo
 
Swift Micro-services and AWS Technologies
Swift Micro-services and AWS TechnologiesSwift Micro-services and AWS Technologies
Swift Micro-services and AWS Technologies
 
Understanding backbonejs
Understanding backbonejsUnderstanding backbonejs
Understanding backbonejs
 
Scalable web application architecture
Scalable web application architectureScalable web application architecture
Scalable web application architecture
 

Recently uploaded

TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubKalema Edgar
 
Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Enterprise Knowledge
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsPixlogix Infotech
 
Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clashcharlottematthew16
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024Lonnie McRorey
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Manik S Magar
 
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo DayH2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo DaySri Ambati
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Mattias Andersson
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfAddepto
 
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfHyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfPrecisely
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteDianaGray10
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024Lorenzo Miniero
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Mark Simos
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 3652toLead Limited
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii SoldatenkoFwdays
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsSergiu Bodiu
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxNavinnSomaal
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsRizwan Syed
 

Recently uploaded (20)

TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding Club
 
Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and Cons
 
Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clash
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!
 
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo DayH2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdf
 
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfHyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test Suite
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platforms
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptx
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL Certs
 
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptxE-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
 

Painless Persistence in a Disconnected World

  • 1. Painless Persistence on Android Christian Melchior @chrmelchior cm@realm.io
  • 2.
  • 3.
  • 4.
  • 5. Why design for offline? • A better USER EXPERIENCE! • You always have something to show the user • Reduce network requests and data transferred • Saves battery
  • 8. They all have a model MVVM MVP MVC VIPER Flux Clean Architecture ModelView getData() data
  • 9. You’re doing it wrong! @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 
 // Setup initial views
 setContentView(R.layout.activity_main);
 
 // Load data and show it
 Retrofit retrofit = new Retrofit.Builder()
 .addConverterFactory(JacksonConverterFactory.create())
 .baseUrl("http://api.nytimes.com/")
 .build();
 
 service = retrofit.create(NYTimesService.class);
 service.topStories("home", "my-key").enqueue(new Callback<NYTimesResponse<List<NYTimesStory>>>() {
 @Override
 public void onResponse(Response<NYTimesResponse<List<NYTimesStory>>> response, Retrofit retrofit) {
 showList(response);
 }
 
 @Override
 public void onFailure(Throwable t) {
 showError(t);
 }
 });
 }

  • 10. You’re doing it right! @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 
 // Setup initial views
 setContentView(R.layout.activity_main);
 
 // Load data and show it
 Model model = ((MyApplication) getApplicationContext()).getModel();
 model.getTopStories(new Observer() {
 @Override
 public void update(Observable observable, NYTimesResponse<List<NYTimesStory>> data) {
 showList(data);
 }
 });
 }

  • 13. Repository pattern • Repository only has CRUD methods: • Create() • Read() • Update() • Delete() • Model and Repository can be tested separately.
  • 14. Designing for offline Repository… DatastoregetData() Observable<Data>() Network Update? Save
  • 15. Designing for offline • Encapsulate data access • The datastore is single-source-of-truth • Everything is asynchronous • Observer pattern • RxJava • EventBus • Testing becomes easier
  • 17. File system • Define hierarchy using folders • No help from the framework • Use cases: Images, JSON blobs
  • 18. File system // App internal files
 context.getFilesDir();
 context.getCacheDir();
 
 // App external files
 context.getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS);
 context.getExternalCacheDir();
 
 // SD Card
 Environment.getExternalStorageDirectory();

  • 19. SharedPreferences • Key-value store • Simple XML file • Use cases: Settings, Key/Value data • Simple API’s and easy to use
  • 20. SharedPreferences // Save data
 SharedPreferences pref = getPreferences(MODE_PRIVATE);
 SharedPreferences.Editor editor = pref.edit();
 editor.putBoolean("key", true);
 editor.commit();
 // Read data boolean data = pref.getBoolean("key", false);

  • 21. Databases • Use cases: Structured data sets • Advanced composing and query capabilities • Complex API’s
  • 22. SQLite vs. the World • SQLite (Relational) • Realm (Object store) • Firebase (Document oriented) • Couchbase Lite (Document oriented) • Parse (Document oriented)
  • 30. SELECT owner.name, dog.name, city.name 
 FROM owner
 INNER JOIN dog ON owner.dog_id = dog.id
 INNER JOIN city ON owner.city_id = city.id
 WHERE owner.name = 'Frank' SQLite
  • 31. String query = "SELECT " + Owner.NAME + ", " + Dog.NAME + ", " + City.NAME 
 + " FROM " + Owner.TABLE_NAME
 + " INNER JOIN " + Dog.TABLE_NAME + " ON " + Owner.DOG_ID + " = " + Dog.ID
 + " INNER JOIN " + City.TABLE_NAME + " ON " + Owner.CITY_ID + " = " + City.ID
 + " WHERE " + Owner.NAME = "'" + escape(queryName) + "'";
 SQLite
  • 32.
  • 33. “Lets use an ORM” Abstract the problem away
  • 34. –Joel Spolsky “All non-trivial abstractions, to some degree, are leaky.”
  • 35. Solved problem? • ActiveRecord • Androrm • Blurb • Cupboard • DBFlow • DBQuery • DBTools • EasyliteOrm • GreenDAO • Ollie • Orman • OrmLite • Persistence • RushORM • Shillelagh • Sprinkles • SquiDB • SugarORM
  • 38. x z y x y z SELECT table1.x, table2.y, table3.z
 FROM table1
 INNER JOIN table2 ON table1.table2_id = table1.id
 INNER JOIN table3 ON table1.table3_id = table3.id
 References in SQL
  • 39. A B C D E F G Realm.getA().getC().getF() Object Store references
  • 40. Zero-copy  Person  {   • name  =  Tommy   • age  =  8   • dog  =  {   • name  =  Lassie          }    }  Person  {   • name  =  Tommy   • age  =  8   • dog  =  {   • name  =  Lassie          }    }  Person  {   • name  =  Tommy   • age  =  8   • dog  =  {   • name  =  Lassie          }    }  PersonProxy  {   • name   • age   • dog      }  PersonProxy  {   • name   • age   • dog      }  Person  {   • name  =  Tommy   • age  =  8   • dog  =  {   • name  =  Lassie          }    } Realm ORM Realm SQLite
  • 41. Benchmarks http://static.realm.io/downloads/java/android-benchmark.zip 1.09% 2.26% 3.79% 4.55% 22.85% 13.37% 1% 1% 1% 1% 1% 1% 0% 5% 10% 15% 20% 25% BatchWrite% SimpleWrite% SimpleQuery% FullScan% Sum% Count% Speedup&vs.&SQLite& Tests&/&1000&objects& Realm% SQLite%
  • 42. SQLite vs. Realm • Part of Android • Relational data model • Based on SQL • Public Domain • One of the most tested pieces of software • Need to map between SQL and Java objects (manually or ORM). • Foreign collections is an unsolvable problem. • Complex API’s • Objects all the way down • Zero copy architecture • Cross-platform • Supports encryption out of the box • Open source* • Custom query language • Will add ~2500 methods + 800 kB of native code. • Still in beta
  • 43. “Talk is cheap. Show me the code.” –Linus Torvalds
  • 44. Adding Realm // ./build.gradle
 buildscript {
 repositories {
 jcenter()
 }
 dependencies {
 classpath 'com.android.tools.build:gradle:2.0.0-alpha1'
 classpath 'io.realm:realm-gradle-plugin:0.86.0'
 }
 }
 // ./app/build.gradle
 apply plugin: 'com.android.application'
 apply plugin: 'realm'

  • 45. Models and Schema public class Person extends RealmObject {
 private String name;
 private int age;
 private Dog dog;
 private RealmList<Cat> cats; // Autogenerated getters/setters
 } public class Cat extends RealmObject {
 private String name;
 // Autogenerated getters/setters
 } public class Dog extends RealmObject {
 private String name;
 // Autogenerated getters/setters
 }
  • 46. Getting an Realm instance // Default configuration. Schema is automatically detected RealmConfiguration config = new RealmConfiguration.Builder(context).build();
 Realm.setDefaultConfiguration(config);
 Realm realm = Realm.getDefaultInstance();
 

  • 47. Create objects - Realm // Create and set persisted objects
 realm.beginTransaction();
 Person person = realm.createObject(Person.class);
 person.setName("Young Person");
 person.setAge(14);
 realm.commitTransaction();
 // Copy java objects
 Person person = new Person();
 person.setName("Young Person");
 person.setAge(14);
 
 realm.beginTransaction();
 realm.copyToRealm(person);
 realm.commitTransaction();
 • Extend RealmObject • POJO: Plain Old Java Object
  • 48. Transactions - Realm // Simple writes
 realm.beginTransaction();
 // ...
 realm.commitTransaction();
 // Automatically handle begin/commit/cancel
 realm.executeTransaction(new Realm.Transaction() {
 @Override
 public void execute(Realm realm) {
 // ...
 }
 });

  • 49. Queries RealmResults<Person> results = realm.where(Person.class) .equalTo("age", 99) .findAll();
 RealmResults<Person> results = realm.where(Person.class) .equalTo("cats.name", “Tiger") .findAll();
 RealmResults<Person> results = realm.where(Person.class) .beginsWith("name", “John") .findAllAsync();
 results.addChangeListener(new RealmChangeListener() {
 @Override
 public void onChange() {
 showResults(results);
 }
 });
 • Fluent queries • Semi-typesafe • Easy async • Always up-to-date
  • 50. Network data // Use Retrofit to parse objects
 Retrofit retrofit = new Retrofit.Builder()
 .addConverterFactory(JacksonConverterFactory.create())
 .baseUrl("http://api.nytimes.com/")
 .build();
 
 MyRestApi service = retrofit.create(MyRestApi.class);
 final Data data = service.getData();
 
 // Copy all data into Realm
 realm.executeTransaction(new Realm.Transaction() {
 @Override
 public void execute(Realm realm) {
 realm.copyToRealmOrUpdate(data);
 }
 });

  • 51. RxJava (Realm) Observable<Realm> observableRealm = realm.asObservable();
 Observable<RealmResults<Person>> results = realm.where(Person.class) .beginsWith("name", “John") .findAllAsync() .asObservable();
 Observable<Person> results = realm.where(Person.class).findFirst().asObservable();
 Observable<RealmQuery> results = realm.where(Person.class).asObservable();

  • 53. Take aways • Not everyone is on Wifi or 4G networks • Encapsulate data access • Designing for offline gives a a better USER EXPERIENCE!
  • 54. Resources • Repository Pattern: http://martinfowler.com/eaaCatalog/ repository.html • Design for offline: https://plus.google.com/ +AndroidDevelopers/posts/3C4GPowmWLb • MVP example: https://www.code-labs.io/codelabs/ android-testing/#0 • Optimizing network requests: https://www.youtube.com/ playlist?list=PLWz5rJ2EKKc9CBxr3BVjPTPoDPLdPIFCE • Realm : https://realm.io/docs/java/latest/