SlideShare a Scribd company logo
1 of 48
Download to read offline
Realm
The Finest Artist
Realm [Relm]
렘 [레엠]
Realm = Kingdom
Realm = Mobile Database
Realm
Replacement for SQLite & Core Data
Android, Android Wear, iOS, OS X, Watch OS
Java, Kotlin, Objective-C, Swift
Why Realm?
Realm
Very Fast
ORM like models & queries
RealmResults auto refresh
More features…
Open source
Documentation in Korean
How Fast?
Gson vs Realm
This test is to compare the speed of Gson and Realm with an extremely simple object model. The overall result of the test shows that Realm
performs a little faster than Gson. However, it could show different results in other test conditions. Refer to the appendix for further information.
Gson.toJson
Gson.fromJson
Realm.createObject
copyToRealm
Milisecond
0 300 600 900 1200
ORM like models & queries
Model
public class User extends RealmObject {
@PrimaryKey
private String name;
private int age;
@Ignore
private int sessionId;
// + Standard getters & setters generated by your IDE
}
Relation
public class Email extends RealmObject {
private String address;
private boolean active;
}
// Many to One
public class Contact extends RealmObject {
private Email email;
}
// Many to Many
public class Contact extends RealmObject {
private RealmList<Email> emails;
}
Write
realm.beginTransaction();
User user = realm.createObject(User.class); // Create a new object
user.setName("John");
user.setEmail("john@corporation.com");
realm.commitTransaction();
Write
User user = new User("John");
user.setEmail("john@corporation.com");
realm.beginTransaction();
realm.copyToRealm(user); // Copy the object to Realm.
realm.copyToRealmOrUpdate(user);
realm.commitTransaction();
Query
// Fluent interface
RealmResults<User> result = realm.where(User.class)
.sort("age");
.beginGroup()
.equalTo("name", "John")
.or()
.equalTo("name", "Peter")
.endGroup()
.findAll();
for (User user : result) {
// do something...
}
Query Options
// Conditions
between(), greaterThan(), lessThan(), greaterThanOrEqualTo() & lessThanOrEqualTo()
equalTo() & notEqualTo()
contains(), beginsWith() & endsWith()
isNull() & isNotNull()
beginsWith() & endsWith() & contains()
// Conditions Grouping
beginGroup() & endGroup() & not() & or()
// Sorting
RealmResults<User> result = realm.where(User.class).findAll();
result.sort("age", RealmResults.SORT_ORDER_DESCENDING);
// Querying
findAll() & findFirst() & findAllSorted()
RealmResults Auto-refresh
RealmResults
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder> {
RealmResults<Post> realmResults;
public RecyclerViewAdapter(Realm realm) {
realmResults = realm.where(Post.class).findAll();
}
@Override
public int getItemCount() { return realmResults.size(); }
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(layoutRes, parent, false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
Post post = realmResults.get(position);
// do something...
}
}
RealmResults
public class UserRecyclerAdapter extends RecyclerView.Adapter<ChatRecyclerAdapter.ViewHolder> {
List<User> users;
public ChatRecyclerAdapter() { /*...*/ }
public void setUsers(List<User> users) { this.users = users; }
@Override
public int getItemCount() { return users == null ? 0 : users.size(); }
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(layoutRes, parent, false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
User user = users.get(position);
/*...*/
}
}
More Features
More Features
Encryption (AES-256)
Multiple Databases
In-Memory Realm
Listeners
Migration
Realm Browser (Mac OS)
Realm Configuration
RealmConfiguration config1 = new RealmConfiguration.Builder(context)
.name("myrealm1.realm")
.encryptionKey(getKey1())
.schemaVersion(1)
.setModules(new MySchemaModule1())
.migration(new MyMigration1())
.build();
RealmConfiguration config2 = new RealmConfiguration.Builder(context)
.name("myrealm2.realm")
.encryptionKey(null)
.inMemory()
.schemaVersion(2)
.setModules(new MySchemaModule2())
.migration(new MyMigration2())
.build();
Realm Listener
private RealmChangeListener realmListener;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
realmListener = new RealmChangeListener() {
@Override
public void onChange() {
// ... do something with the updates (UI, etc.) ...
}
};
realm.addChangeListener(realmListener);
}
@Override
public void onDestroy() {
super.onDestroy();
realm.removeChangeListener(realmListener);
}
Realm Migration
public class Migration implements RealmMigration {
@Override
public long execute(Realm realm, long version) {
// Migrate from version 0 to version 1
if (version == 0) {
Table personTable = realm.getTable(Person.class);
long fistNameIndex = getIndexForProperty(personTable, "firstName");
long lastNameIndex = getIndexForProperty(personTable, "lastName");
long fullNameIndex = personTable.addColumn(ColumnType.STRING, "fullName");
personTable.removeColumn(getIndexForProperty(personTable, "firstName"));
personTable.removeColumn(getIndexForProperty(personTable, "lastName"));
version++;
}
return version;
}
}
https://github.com/realm/realm-java/blob/master/examples/migrationExample
Realm Browser
Open Source
Documentation in Korean
Current Limitations
RealmObject
Only private field
Only default getter & setter
Static field & method are allowed
Null Values
Threads
Users
More
Homepage: http://realm.io/
Facebook: http://fb.com/groups/realmkr
Email: kr@realm.io
Use Case
InstagRealm
https://github.com/TheFinestArtist/InstagRealm
InstagRealm
Features
Instagram Tag API
ScrollView, ListView, RecyclerView, CardView
Infinite Scroll (Paging), Swipe to Refresh
Retrofit
Gson
EventBus
Royal
Fresco, Butterknife, RecyclerView-Animator, Logger
Flow
Retrofit (Instagram Tag API)
=> Gson (Serialize)
=> Realm (Insert data)
=> EventBus
=> Update UI & Notify Adpater
RestAdapter
private static Gson gson = new GsonBuilder()
.setExclusionStrategies(new ExclusionStrategy() {
@Override
public boolean shouldSkipField(FieldAttributes f) {
return f.getDeclaringClass().equals(RealmObject.class);
}
@Override
public boolean shouldSkipClass(Class<?> clazz) {
return false;
}
})
.create();
private static RestAdapter restAdapter = new RestAdapter.Builder()
.setEndpoint(END_POINT)
.setConverter(new GsonConverter(gson))
.setRequestInterceptor(requestInterceptor)
.build();
private static InstagramService instagramService = restAdapter.create(InstagramService.class);
Instagram API
public static void getTag(final Activity activity, final Class<? extends RoyalDatabase> clazz, String next) {
instagramService.getTags("art", accessToken, next, new Callback<TagsCallback>() {
@Override
public void success(TagsCallback tagsCallback, Response response) {
RoyalTransaction.save(clazz, tagsCallback.data);
if (ScrollViewDatabase.class.equals(clazz))
EventBus.getDefault().post(new OnScrollViewUpdateEvent(tagsCallback.pagination.next_max_tag_id, tagsCallback.data));
if (ListViewDatabase.class.equals(clazz))
EventBus.getDefault().post(new OnListViewUpdateEvent(tagsCallback.pagination.next_max_tag_id));
if (RecyclerViewDatabase.class.equals(clazz))
EventBus.getDefault().post(new OnRecyclerViewUpdateEvent(tagsCallback.pagination.next_max_tag_id));
if (CardViewDatabase.class.equals(clazz))
EventBus.getDefault().post(new OnCardViewUpdateEvent(tagsCallback.pagination.next_max_tag_id));
}
@Override
public void failure(RetrofitError error) {
SnackBar.alert(activity, "Please check your network status!");
}
});
}
OnEvent
int itemCount = 0;
public void onEvent(OnRecyclerViewUpdateEvent event) {
swipeRefreshLayout.setRefreshing(false);
if (event.isFailed())
return;
next = event.getNext();
if (itemCount < adapter.getItemCount())
adapter.notifyItemRangeInserted(itemCount, adapter.getItemCount() - itemCount);
else
adapter.notifyItemRangeRemoved(itemCount, itemCount - adapter.getItemCount());
itemCount = adapter.getItemCount();
}
RecyclerViewAdapter
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder> {
RealmResults<Post> realmResults;
public RecyclerViewAdapter(Realm realm) {
realmResults = realm.where(Post.class).findAll();
}
@Override
public int getItemCount() { return realmResults.size(); }
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(layoutRes, parent, false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
Post post = realmResults.get(position);
// do something...
}
}
ListViewAdapter
public class ListViewAdapter extends RealmBaseAdapter<Post> implements ListAdapter {
public ListViewAdapter(Context context, RealmResults<Post> realmResults) {
super(context, realmResults, true);
}
static class ViewHolder {
ViewHolder(View view) { /*...*/ }
public void setPost(Post post) { /*...*/ }
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder;
/* ViewHolder Inflating */
Post post = realmResults.get(position);
viewHolder.setPost(post);
return convertView;
}
}
Use Case
InstagRealm
https://github.com/TheFinestArtist/InstagRealm
Thank You :)
Appendix
Test Device: Galaxy S3
Test Model
public class Contact {
public String address;
public String number;
public boolean active;
}
10000 times iteration per each test.
5 times test per each method
Test Code: https://github.com/Test-Codes/Realm-Java-Benchmark

More Related Content

What's hot

JJUG CCC 2011 Spring
JJUG CCC 2011 SpringJJUG CCC 2011 Spring
JJUG CCC 2011 Spring
Kiyotaka Oku
 

What's hot (20)

Dpilot Source Code With ScreenShots
Dpilot Source Code With ScreenShots Dpilot Source Code With ScreenShots
Dpilot Source Code With ScreenShots
 
Nativescript angular
Nativescript angularNativescript angular
Nativescript angular
 
Firebase ng2 zurich
Firebase ng2 zurichFirebase ng2 zurich
Firebase ng2 zurich
 
ES6 PPT FOR 2016
ES6 PPT FOR 2016ES6 PPT FOR 2016
ES6 PPT FOR 2016
 
ES6 in Real Life
ES6 in Real LifeES6 in Real Life
ES6 in Real Life
 
Advanced Object-Oriented JavaScript
Advanced Object-Oriented JavaScriptAdvanced Object-Oriented JavaScript
Advanced Object-Oriented JavaScript
 
Auto-GWT : Better GWT Programming with Xtend
Auto-GWT : Better GWT Programming with XtendAuto-GWT : Better GWT Programming with Xtend
Auto-GWT : Better GWT Programming with Xtend
 
Async Redux Actions With RxJS - React Rally 2016
Async Redux Actions With RxJS - React Rally 2016Async Redux Actions With RxJS - React Rally 2016
Async Redux Actions With RxJS - React Rally 2016
 
Node Boot Camp
Node Boot CampNode Boot Camp
Node Boot Camp
 
Rxjs swetugg
Rxjs swetuggRxjs swetugg
Rxjs swetugg
 
Stubる - Mockingjayを使ったHTTPクライアントのテスト -
Stubる - Mockingjayを使ったHTTPクライアントのテスト -Stubる - Mockingjayを使ったHTTPクライアントのテスト -
Stubる - Mockingjayを使ったHTTPクライアントのテスト -
 
Gwt and Xtend
Gwt and XtendGwt and Xtend
Gwt and Xtend
 
Green dao
Green daoGreen dao
Green dao
 
Async Frontiers
Async FrontiersAsync Frontiers
Async Frontiers
 
Proxies are Awesome!
Proxies are Awesome!Proxies are Awesome!
Proxies are Awesome!
 
Introduction to Ecmascript - ES6
Introduction to Ecmascript - ES6Introduction to Ecmascript - ES6
Introduction to Ecmascript - ES6
 
Programming with Python and PostgreSQL
Programming with Python and PostgreSQLProgramming with Python and PostgreSQL
Programming with Python and PostgreSQL
 
Rxjs ppt
Rxjs pptRxjs ppt
Rxjs ppt
 
Talk KVO with rac by Philippe Converset
Talk KVO with rac by Philippe ConversetTalk KVO with rac by Philippe Converset
Talk KVO with rac by Philippe Converset
 
JJUG CCC 2011 Spring
JJUG CCC 2011 SpringJJUG CCC 2011 Spring
JJUG CCC 2011 Spring
 

Viewers also liked

Viewers also liked (10)

Realm Presentation
Realm PresentationRealm Presentation
Realm Presentation
 
Introduction to Realm Mobile Platform
Introduction to Realm Mobile PlatformIntroduction to Realm Mobile Platform
Introduction to Realm Mobile Platform
 
Realm of the Mobile Database: an introduction to Realm
Realm of the Mobile Database: an introduction to RealmRealm of the Mobile Database: an introduction to Realm
Realm of the Mobile Database: an introduction to Realm
 
Realm database
Realm databaseRealm database
Realm database
 
Google Dev Fest 2016 - Realm database
Google Dev Fest 2016 - Realm databaseGoogle Dev Fest 2016 - Realm database
Google Dev Fest 2016 - Realm database
 
Realm Mobile Database - An Introduction
Realm Mobile Database - An IntroductionRealm Mobile Database - An Introduction
Realm Mobile Database - An Introduction
 
Realm 코딩카페 - 이종찬
Realm   코딩카페 - 이종찬Realm   코딩카페 - 이종찬
Realm 코딩카페 - 이종찬
 
2015 Upload Campaigns Calendar - SlideShare
2015 Upload Campaigns Calendar - SlideShare2015 Upload Campaigns Calendar - SlideShare
2015 Upload Campaigns Calendar - SlideShare
 
What to Upload to SlideShare
What to Upload to SlideShareWhat to Upload to SlideShare
What to Upload to SlideShare
 
Getting Started With SlideShare
Getting Started With SlideShareGetting Started With SlideShare
Getting Started With SlideShare
 

Similar to Why realm?

Droidcon2013 android experience lahoda
Droidcon2013 android experience lahodaDroidcon2013 android experience lahoda
Droidcon2013 android experience lahoda
Droidcon Berlin
 
Ipc: aidl sexy, not a curse
Ipc: aidl sexy, not a curseIpc: aidl sexy, not a curse
Ipc: aidl sexy, not a curse
Yonatan Levin
 
Android Best Practices
Android Best PracticesAndroid Best Practices
Android Best Practices
Yekmer Simsek
 

Similar to Why realm? (20)

A GWT Application with MVP Pattern Deploying to CloudFoundry using Spring Roo
A GWT Application with MVP Pattern Deploying to CloudFoundry using  Spring Roo A GWT Application with MVP Pattern Deploying to CloudFoundry using  Spring Roo
A GWT Application with MVP Pattern Deploying to CloudFoundry using Spring Roo
 
Realm or: How I learned to stop worrying and love my app database
Realm or: How I learned to stop worrying and love my app databaseRealm or: How I learned to stop worrying and love my app database
Realm or: How I learned to stop worrying and love my app database
 
An intro to cqrs
An intro to cqrsAn intro to cqrs
An intro to cqrs
 
Improving android experience for both users and developers
Improving android experience for both users and developersImproving android experience for both users and developers
Improving android experience for both users and developers
 
Droidcon2013 android experience lahoda
Droidcon2013 android experience lahodaDroidcon2013 android experience lahoda
Droidcon2013 android experience lahoda
 
IPC: AIDL is sexy, not a curse
IPC: AIDL is sexy, not a curseIPC: AIDL is sexy, not a curse
IPC: AIDL is sexy, not a curse
 
Ipc: aidl sexy, not a curse
Ipc: aidl sexy, not a curseIpc: aidl sexy, not a curse
Ipc: aidl sexy, not a curse
 
Android dev toolbox
Android dev toolboxAndroid dev toolbox
Android dev toolbox
 
SOLID Principles
SOLID PrinciplesSOLID Principles
SOLID Principles
 
Architecture components - IT Talk
Architecture components - IT TalkArchitecture components - IT Talk
Architecture components - IT Talk
 
Architecture Components
Architecture Components Architecture Components
Architecture Components
 
Scala on Your Phone
Scala on Your PhoneScala on Your Phone
Scala on Your Phone
 
Durable functions 2.0 (2019-10-10)
Durable functions 2.0 (2019-10-10)Durable functions 2.0 (2019-10-10)
Durable functions 2.0 (2019-10-10)
 
Crossing platforms with JavaScript & React
Crossing platforms with JavaScript & React Crossing platforms with JavaScript & React
Crossing platforms with JavaScript & React
 
Androidppt 1
Androidppt 1Androidppt 1
Androidppt 1
 
Speed up your Web applications with HTML5 WebSockets
Speed up your Web applications with HTML5 WebSocketsSpeed up your Web applications with HTML5 WebSockets
Speed up your Web applications with HTML5 WebSockets
 
比XML更好用的Java Annotation
比XML更好用的Java Annotation比XML更好用的Java Annotation
比XML更好用的Java Annotation
 
Android and the Seven Dwarfs from Devox'15
Android and the Seven Dwarfs from Devox'15Android and the Seven Dwarfs from Devox'15
Android and the Seven Dwarfs from Devox'15
 
Android workshop
Android workshopAndroid workshop
Android workshop
 
Android Best Practices
Android Best PracticesAndroid Best Practices
Android Best Practices
 

Recently uploaded

Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Victor Rentea
 

Recently uploaded (20)

CNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In PakistanCNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In Pakistan
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challenges
 
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
 
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf
 
MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectors
 
Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024
 
FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024
 

Why realm?

  • 5. Realm = Mobile Database
  • 6. Realm Replacement for SQLite & Core Data Android, Android Wear, iOS, OS X, Watch OS Java, Kotlin, Objective-C, Swift
  • 8. Realm Very Fast ORM like models & queries RealmResults auto refresh More features… Open source Documentation in Korean
  • 10.
  • 11.
  • 12.
  • 13. Gson vs Realm This test is to compare the speed of Gson and Realm with an extremely simple object model. The overall result of the test shows that Realm performs a little faster than Gson. However, it could show different results in other test conditions. Refer to the appendix for further information. Gson.toJson Gson.fromJson Realm.createObject copyToRealm Milisecond 0 300 600 900 1200
  • 14. ORM like models & queries
  • 15. Model public class User extends RealmObject { @PrimaryKey private String name; private int age; @Ignore private int sessionId; // + Standard getters & setters generated by your IDE }
  • 16. Relation public class Email extends RealmObject { private String address; private boolean active; } // Many to One public class Contact extends RealmObject { private Email email; } // Many to Many public class Contact extends RealmObject { private RealmList<Email> emails; }
  • 17. Write realm.beginTransaction(); User user = realm.createObject(User.class); // Create a new object user.setName("John"); user.setEmail("john@corporation.com"); realm.commitTransaction();
  • 18. Write User user = new User("John"); user.setEmail("john@corporation.com"); realm.beginTransaction(); realm.copyToRealm(user); // Copy the object to Realm. realm.copyToRealmOrUpdate(user); realm.commitTransaction();
  • 19. Query // Fluent interface RealmResults<User> result = realm.where(User.class) .sort("age"); .beginGroup() .equalTo("name", "John") .or() .equalTo("name", "Peter") .endGroup() .findAll(); for (User user : result) { // do something... }
  • 20. Query Options // Conditions between(), greaterThan(), lessThan(), greaterThanOrEqualTo() & lessThanOrEqualTo() equalTo() & notEqualTo() contains(), beginsWith() & endsWith() isNull() & isNotNull() beginsWith() & endsWith() & contains() // Conditions Grouping beginGroup() & endGroup() & not() & or() // Sorting RealmResults<User> result = realm.where(User.class).findAll(); result.sort("age", RealmResults.SORT_ORDER_DESCENDING); // Querying findAll() & findFirst() & findAllSorted()
  • 22. RealmResults public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder> { RealmResults<Post> realmResults; public RecyclerViewAdapter(Realm realm) { realmResults = realm.where(Post.class).findAll(); } @Override public int getItemCount() { return realmResults.size(); } @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()).inflate(layoutRes, parent, false); return new ViewHolder(view); } @Override public void onBindViewHolder(ViewHolder holder, int position) { Post post = realmResults.get(position); // do something... } }
  • 23. RealmResults public class UserRecyclerAdapter extends RecyclerView.Adapter<ChatRecyclerAdapter.ViewHolder> { List<User> users; public ChatRecyclerAdapter() { /*...*/ } public void setUsers(List<User> users) { this.users = users; } @Override public int getItemCount() { return users == null ? 0 : users.size(); } @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()).inflate(layoutRes, parent, false); return new ViewHolder(view); } @Override public void onBindViewHolder(ViewHolder holder, int position) { User user = users.get(position); /*...*/ } }
  • 25. More Features Encryption (AES-256) Multiple Databases In-Memory Realm Listeners Migration Realm Browser (Mac OS)
  • 26. Realm Configuration RealmConfiguration config1 = new RealmConfiguration.Builder(context) .name("myrealm1.realm") .encryptionKey(getKey1()) .schemaVersion(1) .setModules(new MySchemaModule1()) .migration(new MyMigration1()) .build(); RealmConfiguration config2 = new RealmConfiguration.Builder(context) .name("myrealm2.realm") .encryptionKey(null) .inMemory() .schemaVersion(2) .setModules(new MySchemaModule2()) .migration(new MyMigration2()) .build();
  • 27. Realm Listener private RealmChangeListener realmListener; @Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); realmListener = new RealmChangeListener() { @Override public void onChange() { // ... do something with the updates (UI, etc.) ... } }; realm.addChangeListener(realmListener); } @Override public void onDestroy() { super.onDestroy(); realm.removeChangeListener(realmListener); }
  • 28. Realm Migration public class Migration implements RealmMigration { @Override public long execute(Realm realm, long version) { // Migrate from version 0 to version 1 if (version == 0) { Table personTable = realm.getTable(Person.class); long fistNameIndex = getIndexForProperty(personTable, "firstName"); long lastNameIndex = getIndexForProperty(personTable, "lastName"); long fullNameIndex = personTable.addColumn(ColumnType.STRING, "fullName"); personTable.removeColumn(getIndexForProperty(personTable, "firstName")); personTable.removeColumn(getIndexForProperty(personTable, "lastName")); version++; } return version; } } https://github.com/realm/realm-java/blob/master/examples/migrationExample
  • 32. Current Limitations RealmObject Only private field Only default getter & setter Static field & method are allowed Null Values Threads
  • 33. Users
  • 37. Features Instagram Tag API ScrollView, ListView, RecyclerView, CardView Infinite Scroll (Paging), Swipe to Refresh Retrofit Gson EventBus Royal Fresco, Butterknife, RecyclerView-Animator, Logger
  • 38. Flow Retrofit (Instagram Tag API) => Gson (Serialize) => Realm (Insert data) => EventBus => Update UI & Notify Adpater
  • 39. RestAdapter private static Gson gson = new GsonBuilder() .setExclusionStrategies(new ExclusionStrategy() { @Override public boolean shouldSkipField(FieldAttributes f) { return f.getDeclaringClass().equals(RealmObject.class); } @Override public boolean shouldSkipClass(Class<?> clazz) { return false; } }) .create(); private static RestAdapter restAdapter = new RestAdapter.Builder() .setEndpoint(END_POINT) .setConverter(new GsonConverter(gson)) .setRequestInterceptor(requestInterceptor) .build(); private static InstagramService instagramService = restAdapter.create(InstagramService.class);
  • 40. Instagram API public static void getTag(final Activity activity, final Class<? extends RoyalDatabase> clazz, String next) { instagramService.getTags("art", accessToken, next, new Callback<TagsCallback>() { @Override public void success(TagsCallback tagsCallback, Response response) { RoyalTransaction.save(clazz, tagsCallback.data); if (ScrollViewDatabase.class.equals(clazz)) EventBus.getDefault().post(new OnScrollViewUpdateEvent(tagsCallback.pagination.next_max_tag_id, tagsCallback.data)); if (ListViewDatabase.class.equals(clazz)) EventBus.getDefault().post(new OnListViewUpdateEvent(tagsCallback.pagination.next_max_tag_id)); if (RecyclerViewDatabase.class.equals(clazz)) EventBus.getDefault().post(new OnRecyclerViewUpdateEvent(tagsCallback.pagination.next_max_tag_id)); if (CardViewDatabase.class.equals(clazz)) EventBus.getDefault().post(new OnCardViewUpdateEvent(tagsCallback.pagination.next_max_tag_id)); } @Override public void failure(RetrofitError error) { SnackBar.alert(activity, "Please check your network status!"); } }); }
  • 41. OnEvent int itemCount = 0; public void onEvent(OnRecyclerViewUpdateEvent event) { swipeRefreshLayout.setRefreshing(false); if (event.isFailed()) return; next = event.getNext(); if (itemCount < adapter.getItemCount()) adapter.notifyItemRangeInserted(itemCount, adapter.getItemCount() - itemCount); else adapter.notifyItemRangeRemoved(itemCount, itemCount - adapter.getItemCount()); itemCount = adapter.getItemCount(); }
  • 42. RecyclerViewAdapter public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder> { RealmResults<Post> realmResults; public RecyclerViewAdapter(Realm realm) { realmResults = realm.where(Post.class).findAll(); } @Override public int getItemCount() { return realmResults.size(); } @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()).inflate(layoutRes, parent, false); return new ViewHolder(view); } @Override public void onBindViewHolder(ViewHolder holder, int position) { Post post = realmResults.get(position); // do something... } }
  • 43. ListViewAdapter public class ListViewAdapter extends RealmBaseAdapter<Post> implements ListAdapter { public ListViewAdapter(Context context, RealmResults<Post> realmResults) { super(context, realmResults, true); } static class ViewHolder { ViewHolder(View view) { /*...*/ } public void setPost(Post post) { /*...*/ } } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder viewHolder; /* ViewHolder Inflating */ Post post = realmResults.get(position); viewHolder.setPost(post); return convertView; } }
  • 45.
  • 46.
  • 48. Appendix Test Device: Galaxy S3 Test Model public class Contact { public String address; public String number; public boolean active; } 10000 times iteration per each test. 5 times test per each method Test Code: https://github.com/Test-Codes/Realm-Java-Benchmark