├── .gitignore ├── LICENSE ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── UserDaoTest.java │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── ls │ │ └── realm │ │ ├── app │ │ └── RealmApplication.java │ │ ├── model │ │ └── db │ │ │ ├── RealmManager.java │ │ │ ├── dao │ │ │ └── UserDao.java │ │ │ ├── data │ │ │ ├── IViewType.java │ │ │ └── User.java │ │ │ └── utils │ │ │ ├── DataGenerator.java │ │ │ └── RealmString.java │ │ └── ui │ │ ├── activity │ │ └── HomeActivity.java │ │ └── adapter │ │ └── RealmAdapter.java │ └── res │ ├── layout │ ├── ac_home.xml │ └── item_user.xml │ ├── mipmap-hdpi │ └── ic_launcher.png │ ├── mipmap-mdpi │ └── ic_launcher.png │ ├── mipmap-xhdpi │ └── ic_launcher.png │ ├── mipmap-xxhdpi │ └── ic_launcher.png │ ├── mipmap-xxxhdpi │ └── ic_launcher.png │ ├── values-v21 │ └── styles.xml │ ├── values-w820dp │ └── dimens.xml │ └── values │ ├── colors.xml │ ├── dimens.xml │ ├── strings.xml │ └── styles.xml ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | ### Android ### 2 | # Built application files 3 | *.apk 4 | *.ap_ 5 | 6 | # Files for the Dalvik VM 7 | *.dex 8 | 9 | # Java class files 10 | *.class 11 | 12 | # Generated files 13 | bin/ 14 | gen/ 15 | 16 | # Gradle files 17 | .gradle/ 18 | build/ 19 | 20 | # Local configuration file (sdk path, etc) 21 | local.properties 22 | 23 | # Proguard folder generated by Eclipse 24 | proguard/ 25 | 26 | # Log Files 27 | *.log 28 | 29 | # Android Studio Navigation editor temp files 30 | .navigation/ 31 | 32 | ### Android Patch ### 33 | gen-external-apklibs 34 | 35 | 36 | ### Intellij ### 37 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio 38 | 39 | *.iml 40 | 41 | ## Directory-based project format: 42 | .idea/ 43 | # if you remove the above rule, at least ignore the following: 44 | 45 | # User-specific stuff: 46 | # .idea/workspace.xml 47 | # .idea/tasks.xml 48 | # .idea/dictionaries 49 | 50 | # Sensitive or high-churn files: 51 | # .idea/dataSources.ids 52 | # .idea/dataSources.xml 53 | # .idea/sqlDataSources.xml 54 | # .idea/dynamic.xml 55 | # .idea/uiDesigner.xml 56 | 57 | # Gradle: 58 | # .idea/gradle.xml 59 | # .idea/libraries 60 | 61 | # Mongo Explorer plugin: 62 | # .idea/mongoSettings.xml 63 | 64 | ## File-based project format: 65 | *.ipr 66 | *.iws 67 | 68 | ## Plugin-specific files: 69 | 70 | # IntelliJ 71 | /out/ 72 | 73 | # mpeltonen/sbt-idea plugin 74 | .idea_modules/ 75 | 76 | # JIRA plugin 77 | atlassian-ide-plugin.xml 78 | 79 | # Crashlytics plugin (for Android Studio and IntelliJ) 80 | com_crashlytics_export_strings.xml 81 | crashlytics.properties 82 | crashlytics-build.properties -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Lemberg Solutions 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | **Realm database** 3 | 4 | Realm Java enables you to efficiently write your app’s model layer in a safe, persisted and fast way. 5 | 6 | **Realm is a replacement for SQLite & Core Data** 7 | 8 | - *Easy to Use* 9 | 10 | Realm is not an ORM on top of SQLite. Instead it uses its own persistence engine, built for simplicity (& speed). 11 | 12 | - *Fast* 13 | 14 | Thanks to its zero-copy design, Realm is much faster than an ORM, and is often faster than raw SQLite as well. 15 | 16 | - *Cross-Platform* 17 | 18 | You can share Realm files across platforms and use the same high-level models. 19 | 20 | See graphic performance comparison to other databases [here](https://realm.io/news/realm-for-android/#realm-for-android). 21 | 22 | **Prerequisites** 23 | 24 | - [Realm](https://realm.io/) do not support Java outside of Android at the moment. 25 | - [Android Studio](http://developer.android.com/sdk/index.html?gclid=COOv_bPoo8oCFcoGcwodcJ4AVQ) >= 0.8.6 26 | - A recent version of the Android SDK. 27 | - JDK version >=7. 28 | - Support all [Android versions](http://developer.android.com/about/dashboards/index.html) since API Level 9 (Android 2.3 Gingerbread & above). 29 | 30 | **Here how it looks like** 31 | 32 | ```java 33 | public class User extends RealmObject { 34 | @PrimaryKey 35 | private long id; 36 | private String firstName; 37 | //basic implementation 38 | } 39 | ``` 40 | ```java 41 | //write single User object 42 | realm.executeTransaction(new Realm.Transaction() { 43 | @Override 44 | public void execute(Realm bgRealm) { 45 | bgRealm.copyToRealmOrUpdate(user); 46 | } 47 | }); 48 | ``` 49 | ```java 50 | //Query to look for all users 51 | realm.where(User.class).findAll(); 52 | ``` 53 | 54 | **Installation** 55 | 56 | 1. Make sure your project uses jcenter as a dependency repository 57 | (default on latest version of the Android Gradle plugin). 58 | 59 | 2. Add compile `'io.realm:realm-android:0.87.2'` to the dependencies of 60 | your project. See latest version on [realm.io](https://realm.io/docs/java/latest/) 61 | 62 | 3. In the Android Studio menu: Tools->Android->Sync Project with Gradle 63 | Files. 64 | 65 | **Best Practices** 66 | 67 | *UI or not UI?* 68 | 69 | - Typically Realm is fast enough to read and write data on Android’s 70 | main thread. However, write transactions are blocking across threads 71 | so in order to prevent accidental Application Not Responding Errors (ANR’s) there are advise to perform 72 | all Realm write operations on a background thread (not Android’s main 73 | thread). 74 | 75 | ```java 76 | RealmResults userList = realm.where(User.class).findAllAsync(); 77 | userList.addChangeListener(new RealmChangeListener() { 78 | @Override 79 | public void onChange() { 80 | //userList is now filled with data 81 | //update UI here 82 | } 83 | }); 84 | ``` 85 | 86 | ```java 87 | realm.executeTransaction(new Realm.Transaction() { 88 | @Override 89 | public void execute(Realm bgRealm) { 90 | bgRealm.copyToRealmOrUpdate(user); 91 | } 92 | }); 93 | ``` 94 | 95 | - However while you working with a small amount of data, don't be afraid to write/load data on UI thread. 96 | See according [Christian Melchior](http://stackoverflow.com/users/1389357/christian-melchior) answer on [StackOverflow](http://stackoverflow.com/questions/27805580/realm-io-and-asynchronous-queries). 97 | 98 | 99 | *Controlling the lifecycle of Realm instances* 100 | 101 | - To avoid the overhead of opening and closing the Realm data 102 | connection, Realm has a reference counted cache internally. This 103 | implies that calling `Realm.getDefaultInstance()` multiple times on the 104 | same thread is free, and the underlying resources will automatically 105 | be released when all instances are closed. 106 | 107 | This means that on the UI thread the easiest and safest approach is 108 | to open a Realm instance in all your Activities and Fragments and 109 | close it again when the `Activity` or `Fragment` is destroyed. 110 | 111 | ```java 112 | public class RealmApplication extends Application { 113 | @Override 114 | public void onCreate() { 115 | super.onCreate(); 116 | RealmConfiguration realmConfiguration = new RealmConfiguration 117 | .Builder(this).build(); 118 | Realm.setDefaultConfiguration(realmConfiguration); 119 | } 120 | } 121 | ``` 122 | ```java 123 | public class RealmActivity extends AppCompatActivity { 124 | 125 | protected Realm mRealm; 126 | 127 | @Override 128 | protected void onCreate(Bundle savedInstanceState) { 129 | super.onCreate(savedInstanceState); 130 | mRealm = Realm.getDefaultInstance(); 131 | } 132 | 133 | @Override 134 | protected void onDestroy() { 135 | super.onDestroy(); 136 | if (mRealm != null) { 137 | mRealm.close(); 138 | } 139 | } 140 | } 141 | ``` 142 | *Reuse RealmResults and RealmObjects* 143 | 144 | - On the UI thread and all other Looper threads, all `RealmObjects` and 145 | `RealmResults` are automatically refreshed when changes are made to the 146 | Realm. This means that it isn’t necessary to fetch those objects 147 | again when reacting to a `RealmChangedListener`. The objects are 148 | already updated and ready to be redrawn on the screen. 149 | 150 | **Keep in mind while using Realm (Limitations)** 151 | 152 | `RealmObject` can have: 153 | 154 | - Only private instance fields. 155 | - Only default getter and setter methods. 156 | - Static fields, both public and private. 157 | - Static methods. 158 | - Implementing interfaces with no methods. 159 | 160 | You can only save objects that extend `RealmObject` inside a Realm. 161 | That means that you have to declare an `RealmList` if you want to save a List, or extend `RealmObject` while saving an object. 162 | 163 | 164 | 165 | See [StackOverflow](http://stackoverflow.com/questions/30097810/listobject-or-realmlistrealmobject-on-realm-android) answer for data saving. 166 | 167 | **More Info** 168 | 169 | See [Realm documentation](https://realm.io/docs/java/latest/) for more details 170 | 171 | **License** 172 | 173 | The MIT License (MIT) 174 | 175 | Copyright (c) 2015 Lemberg Solutions 176 | 177 | Permission is hereby granted, free of charge, to any person obtaining a copy 178 | of this software and associated documentation files (the "Software"), to deal 179 | in the Software without restriction, including without limitation the rights 180 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 181 | copies of the Software, and to permit persons to whom the Software is 182 | furnished to do so, subject to the following conditions: 183 | 184 | The above copyright notice and this permission notice shall be included in all 185 | copies or substantial portions of the Software. 186 | 187 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 188 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 189 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 190 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 191 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 192 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 193 | SOFTWARE. 194 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | ### Android ### 2 | # Built application files 3 | *.apk 4 | *.ap_ 5 | 6 | # Files for the Dalvik VM 7 | *.dex 8 | 9 | # Java class files 10 | *.class 11 | 12 | # Generated files 13 | bin/ 14 | gen/ 15 | 16 | # Gradle files 17 | .gradle/ 18 | build/ 19 | 20 | # Local configuration file (sdk path, etc) 21 | local.properties 22 | 23 | # Proguard folder generated by Eclipse 24 | proguard/ 25 | 26 | # Log Files 27 | *.log 28 | 29 | # Android Studio Navigation editor temp files 30 | .navigation/ 31 | 32 | ### Android Patch ### 33 | gen-external-apklibs 34 | 35 | 36 | ### Intellij ### 37 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio 38 | 39 | *.iml 40 | 41 | ## Directory-based project format: 42 | .idea/ 43 | # if you remove the above rule, at least ignore the following: 44 | 45 | # User-specific stuff: 46 | # .idea/workspace.xml 47 | # .idea/tasks.xml 48 | # .idea/dictionaries 49 | 50 | # Sensitive or high-churn files: 51 | # .idea/dataSources.ids 52 | # .idea/dataSources.xml 53 | # .idea/sqlDataSources.xml 54 | # .idea/dynamic.xml 55 | # .idea/uiDesigner.xml 56 | 57 | # Gradle: 58 | # .idea/gradle.xml 59 | # .idea/libraries 60 | 61 | # Mongo Explorer plugin: 62 | # .idea/mongoSettings.xml 63 | 64 | ## File-based project format: 65 | *.ipr 66 | *.iws 67 | 68 | ## Plugin-specific files: 69 | 70 | # IntelliJ 71 | /out/ 72 | 73 | # mpeltonen/sbt-idea plugin 74 | .idea_modules/ 75 | 76 | # JIRA plugin 77 | atlassian-ide-plugin.xml 78 | 79 | # Crashlytics plugin (for Android Studio and IntelliJ) 80 | com_crashlytics_export_strings.xml 81 | crashlytics.properties 82 | crashlytics-build.properties -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 23 5 | buildToolsVersion "23.0.2" 6 | 7 | defaultConfig { 8 | applicationId "com.rd.testproject" 9 | minSdkVersion 15 10 | targetSdkVersion 23 11 | versionCode 1 12 | versionName "1.0" 13 | } 14 | buildTypes { 15 | release { 16 | minifyEnabled false 17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 18 | } 19 | } 20 | } 21 | 22 | dependencies { 23 | compile fileTree(dir: 'libs', include: ['*.jar']) 24 | testCompile 'junit:junit:4.12' 25 | compile 'com.android.support:appcompat-v7:23.1.1' 26 | compile 'com.android.support:design:23.1.1' 27 | compile 'com.android.support:cardview-v7:23.1.1' 28 | compile 'com.android.support:recyclerview-v7:23.1.1' 29 | compile 'io.realm:realm-android:0.87.2' 30 | } 31 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in D:\Work\IDE\sdk\orion-sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /app/src/androidTest/java/UserDaoTest.java: -------------------------------------------------------------------------------- 1 | import android.content.Context; 2 | import android.test.InstrumentationTestCase; 3 | 4 | import com.ls.realm.model.db.RealmManager; 5 | import com.ls.realm.model.db.dao.UserDao; 6 | import com.ls.realm.model.db.data.User; 7 | import com.ls.realm.model.db.utils.DataGenerator; 8 | 9 | import java.util.List; 10 | 11 | import io.realm.Realm; 12 | import io.realm.RealmConfiguration; 13 | import io.realm.RealmObject; 14 | 15 | public class UserDaoTest extends InstrumentationTestCase { 16 | 17 | private Realm mRealm; 18 | 19 | @Override 20 | protected void setUp() throws Exception { 21 | super.setUp(); 22 | 23 | Context context = getInstrumentation().getTargetContext(); 24 | RealmConfiguration realmConfiguration = new RealmConfiguration.Builder(context).build(); 25 | Realm.setDefaultConfiguration(realmConfiguration); 26 | 27 | mRealm = RealmManager.open(); 28 | RealmManager.clear(); 29 | } 30 | 31 | @Override 32 | protected void tearDown() throws Exception { 33 | super.tearDown(); 34 | RealmManager.clear(); 35 | mRealm.close(); 36 | } 37 | 38 | public void testSaveUser() throws Exception { 39 | User saveUser = DataGenerator.generateUser(); 40 | 41 | UserDao dao = RealmManager.createUserDao(); 42 | dao.save(saveUser); 43 | User loadUser = (User) dao.loadBy(saveUser.getId()); 44 | 45 | boolean isEquals = User.equals(saveUser, loadUser); 46 | assertTrue("Users are not equal", isEquals); 47 | } 48 | 49 | public void testSaveUserList() { 50 | List saveList = DataGenerator.generateUserList(); 51 | 52 | UserDao dao = RealmManager.createUserDao(); 53 | dao.save(saveList); 54 | List loadList = dao.loadAll(); 55 | 56 | boolean isEquals = User.equals(saveList, loadList); 57 | assertTrue("Users Lists are not equal", isEquals); 58 | } 59 | 60 | public void testLoadBy() { 61 | User saveUser = DataGenerator.generateUser(); 62 | 63 | UserDao dao = RealmManager.createUserDao(); 64 | dao.save(saveUser); 65 | User loadUser = (User) dao.loadBy(saveUser.getId()); 66 | 67 | boolean isEquals = User.equals(saveUser, loadUser); 68 | assertTrue(isEquals); 69 | } 70 | 71 | public void testRemove() { 72 | User saveUser = DataGenerator.generateUser(); 73 | 74 | UserDao dao = RealmManager.createUserDao(); 75 | dao.save(saveUser); 76 | 77 | RealmObject realmObject = dao.loadBy(saveUser.getId()); 78 | dao.remove(realmObject); 79 | 80 | boolean isEmpty = dao.count() == 0; 81 | assertTrue("User table is not empty", isEmpty); 82 | } 83 | 84 | public void testRemoveAll() { 85 | List saveList = DataGenerator.generateUserList(); 86 | 87 | UserDao dao = RealmManager.createUserDao(); 88 | dao.save(saveList); 89 | dao.removeAll(); 90 | 91 | boolean isEmpty = dao.count() == 0; 92 | assertTrue("User table is not empty", isEmpty); 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 12 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /app/src/main/java/com/ls/realm/app/RealmApplication.java: -------------------------------------------------------------------------------- 1 | package com.ls.realm.app; 2 | 3 | import android.app.Application; 4 | 5 | import io.realm.Realm; 6 | import io.realm.RealmConfiguration; 7 | 8 | public class RealmApplication extends Application { 9 | @Override 10 | public void onCreate() { 11 | super.onCreate(); 12 | 13 | RealmConfiguration realmConfiguration = 14 | new RealmConfiguration.Builder(this) 15 | .name("realm-sample.db") 16 | .schemaVersion(1) 17 | .build(); 18 | 19 | Realm.setDefaultConfiguration(realmConfiguration); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /app/src/main/java/com/ls/realm/model/db/RealmManager.java: -------------------------------------------------------------------------------- 1 | package com.ls.realm.model.db; 2 | 3 | import com.ls.realm.model.db.dao.UserDao; 4 | import com.ls.realm.model.db.data.User; 5 | 6 | import io.realm.Realm; 7 | 8 | public class RealmManager { 9 | 10 | private static Realm mRealm; 11 | 12 | public static Realm open() { 13 | mRealm = Realm.getDefaultInstance(); 14 | return mRealm; 15 | } 16 | 17 | public static void close() { 18 | if (mRealm != null) { 19 | mRealm.close(); 20 | } 21 | } 22 | 23 | public static UserDao createUserDao() { 24 | checkForOpenRealm(); 25 | return new UserDao(mRealm); 26 | } 27 | 28 | public static void clear() { 29 | checkForOpenRealm(); 30 | mRealm.executeTransaction(new Realm.Transaction() { 31 | @Override 32 | public void execute(Realm realm) { 33 | realm.clear(User.class); 34 | //clear rest of your dao classes 35 | } 36 | }); 37 | } 38 | 39 | private static void checkForOpenRealm() { 40 | if (mRealm == null || mRealm.isClosed()) { 41 | throw new IllegalStateException("RealmManager: Realm is closed, call open() method first"); 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /app/src/main/java/com/ls/realm/model/db/dao/UserDao.java: -------------------------------------------------------------------------------- 1 | package com.ls.realm.model.db.dao; 2 | 3 | import android.support.annotation.NonNull; 4 | 5 | import com.ls.realm.model.db.data.User; 6 | 7 | import java.util.List; 8 | 9 | import io.realm.Realm; 10 | import io.realm.RealmObject; 11 | import io.realm.RealmResults; 12 | 13 | public class UserDao { 14 | 15 | private Realm mRealm; 16 | 17 | public UserDao(@NonNull Realm realm) { 18 | mRealm = realm; 19 | } 20 | 21 | public void save(final User user) { 22 | mRealm.executeTransaction(new Realm.Transaction() { 23 | @Override 24 | public void execute(Realm realm) { 25 | realm.copyToRealmOrUpdate(user); 26 | } 27 | }); 28 | } 29 | 30 | public void save(final List userList) { 31 | mRealm.executeTransaction(new Realm.Transaction() { 32 | @Override 33 | public void execute(Realm realm) { 34 | realm.copyToRealmOrUpdate(userList); 35 | } 36 | }); 37 | } 38 | 39 | public RealmResults loadAll() { 40 | return mRealm.where(User.class).findAllSorted("id"); 41 | } 42 | 43 | public RealmResults loadAllAsync() { 44 | return mRealm.where(User.class).findAllSortedAsync("id"); 45 | } 46 | 47 | public RealmObject loadBy(long id) { 48 | return mRealm.where(User.class).equalTo("id", id).findFirst(); 49 | } 50 | 51 | public void remove(@NonNull final RealmObject object) { 52 | mRealm.executeTransaction(new Realm.Transaction() { 53 | @Override 54 | public void execute(Realm realm) { 55 | object.removeFromRealm(); 56 | } 57 | }); 58 | } 59 | 60 | public void removeAll() { 61 | mRealm.executeTransaction(new Realm.Transaction() { 62 | @Override 63 | public void execute(Realm realm) { 64 | mRealm.clear(User.class); 65 | } 66 | }); 67 | } 68 | 69 | public long count() { 70 | return mRealm.where(User.class).count(); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /app/src/main/java/com/ls/realm/model/db/data/IViewType.java: -------------------------------------------------------------------------------- 1 | package com.ls.realm.model.db.data; 2 | 3 | public interface IViewType { 4 | } 5 | -------------------------------------------------------------------------------- /app/src/main/java/com/ls/realm/model/db/data/User.java: -------------------------------------------------------------------------------- 1 | package com.ls.realm.model.db.data; 2 | 3 | import com.ls.realm.model.db.utils.RealmString; 4 | 5 | import java.util.List; 6 | 7 | import io.realm.RealmList; 8 | import io.realm.RealmObject; 9 | import io.realm.annotations.PrimaryKey; 10 | 11 | public class User extends RealmObject implements IViewType { 12 | 13 | @PrimaryKey 14 | private long id; 15 | private String firstName; 16 | private String lastName; 17 | private String email; 18 | private int age; 19 | 20 | private RealmList contactList; 21 | 22 | public User() { 23 | contactList = new RealmList<>(); 24 | } 25 | 26 | public long getId() { 27 | return id; 28 | } 29 | 30 | public void setId(long id) { 31 | this.id = id; 32 | } 33 | 34 | public String getFirstName() { 35 | return firstName; 36 | } 37 | 38 | public void setFirstName(String firstName) { 39 | this.firstName = firstName; 40 | } 41 | 42 | public String getLastName() { 43 | return lastName; 44 | } 45 | 46 | public void setLastName(String lastName) { 47 | this.lastName = lastName; 48 | } 49 | 50 | public int getAge() { 51 | return age; 52 | } 53 | 54 | public void setAge(int age) { 55 | this.age = age; 56 | } 57 | 58 | public String getEmail() { 59 | return email; 60 | } 61 | 62 | public void setEmail(String email) { 63 | this.email = email; 64 | } 65 | 66 | public RealmList getContactList() { 67 | return contactList; 68 | } 69 | 70 | public void setContactList(RealmList contactList) { 71 | this.contactList = contactList; 72 | } 73 | 74 | public static boolean equals(List userList1, List userList2) { 75 | boolean isEquals = true; 76 | 77 | if (userList1 != null && userList2 != null && userList1.size() == userList2.size()) { 78 | for (int i = 0; i < userList1.size(); i++) { 79 | User user1 = userList1.get(i); 80 | User user2 = userList2.get(i); 81 | 82 | if (!equals(user1, user2)) { 83 | isEquals = false; 84 | break; 85 | } 86 | } 87 | } else { 88 | isEquals = false; 89 | } 90 | 91 | return isEquals; 92 | } 93 | 94 | public static boolean equals(User user1, User user2) { 95 | if (user1.getId() != user2.getId()) return false; 96 | 97 | if (user1.getAge() != user2.getAge()) return false; 98 | 99 | if (user1.getFirstName() == null || user2.getFirstName() == null || !user1.getFirstName().equals(user2.getFirstName())) 100 | return false; 101 | 102 | if (user1.getLastName() == null || user2.getLastName() == null || !user1.getLastName().equals(user2.getLastName())) 103 | return false; 104 | 105 | if (user1.getEmail() == null || user2.getEmail() == null || !user1.getEmail().equals(user2.getEmail())) 106 | return false; 107 | 108 | if (user1.getContactList() != null && user2.getContactList() != null && user1.getContactList().size() == user2.getContactList().size()) { 109 | for (int i = 0; i < user1.getContactList().size(); i++) { 110 | String contact1 = user1.getContactList().get(i).getString(); 111 | String contact2 = user2.getContactList().get(i).getString(); 112 | 113 | if (!contact1.equals(contact2)) { 114 | return false; 115 | } 116 | } 117 | } 118 | 119 | return true; 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /app/src/main/java/com/ls/realm/model/db/utils/DataGenerator.java: -------------------------------------------------------------------------------- 1 | package com.ls.realm.model.db.utils; 2 | 3 | import android.support.annotation.NonNull; 4 | 5 | import com.ls.realm.model.db.data.User; 6 | 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | 10 | import io.realm.RealmList; 11 | 12 | public class DataGenerator { 13 | 14 | @NonNull 15 | public static List generateUserList() { 16 | List userList = new ArrayList<>(); 17 | 18 | for (int i = 1; i <= 100; i++) { 19 | User user = new User(); 20 | user.setId(i); 21 | user.setFirstName("John" + i); 22 | user.setLastName("Doe" + i); 23 | user.setAge(i + 20); 24 | user.setEmail(String.format("JohnDoe%d@gmail.com", i)); 25 | user.getContactList().addAll(generateContactList()); 26 | 27 | userList.add(user); 28 | } 29 | 30 | return userList; 31 | } 32 | 33 | public static User generateUser() { 34 | User user = new User(); 35 | user.setId(1); 36 | user.setAge(22); 37 | user.setEmail("user@gmail.com"); 38 | user.setFirstName("John"); 39 | user.setLastName("Doe"); 40 | user.setContactList(generateContactList()); 41 | return user; 42 | } 43 | 44 | private static RealmList generateContactList() { 45 | RealmList contactList = new RealmList<>(); 46 | for (int i = 0; i < 3; i++) { 47 | contactList.add(new RealmString("Contact " + i)); 48 | } 49 | return contactList; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /app/src/main/java/com/ls/realm/model/db/utils/RealmString.java: -------------------------------------------------------------------------------- 1 | package com.ls.realm.model.db.utils; 2 | 3 | import io.realm.RealmObject; 4 | 5 | public class RealmString extends RealmObject { 6 | 7 | private String string; 8 | 9 | public RealmString() {} 10 | 11 | public RealmString(String str) { 12 | string = str; 13 | } 14 | 15 | public String getString() { 16 | return string; 17 | } 18 | 19 | public void setString(String string) { 20 | this.string = string; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /app/src/main/java/com/ls/realm/ui/activity/HomeActivity.java: -------------------------------------------------------------------------------- 1 | package com.ls.realm.ui.activity; 2 | 3 | import android.os.Bundle; 4 | import android.support.v7.app.AppCompatActivity; 5 | import android.support.v7.widget.DefaultItemAnimator; 6 | import android.support.v7.widget.LinearLayoutManager; 7 | import android.support.v7.widget.RecyclerView; 8 | 9 | import com.ls.realm.R; 10 | import com.ls.realm.model.db.RealmManager; 11 | import com.ls.realm.model.db.data.User; 12 | import com.ls.realm.model.db.utils.DataGenerator; 13 | import com.ls.realm.ui.adapter.RealmAdapter; 14 | 15 | import java.util.List; 16 | 17 | import io.realm.RealmChangeListener; 18 | import io.realm.RealmResults; 19 | 20 | public class HomeActivity extends AppCompatActivity { 21 | 22 | private RealmAdapter mAdapter; 23 | 24 | @Override 25 | protected void onCreate(Bundle savedInstanceState) { 26 | super.onCreate(savedInstanceState); 27 | setContentView(R.layout.ac_home); 28 | RealmManager.open(); 29 | 30 | initViews(); 31 | saveUserList(); 32 | loadUserListAsync(); 33 | } 34 | 35 | @Override 36 | protected void onDestroy() { 37 | RealmManager.close(); 38 | super.onDestroy(); 39 | } 40 | 41 | private void initViews() { 42 | mAdapter = new RealmAdapter(); 43 | 44 | LinearLayoutManager layoutManager = new LinearLayoutManager(this); 45 | RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerView); 46 | recyclerView.setHasFixedSize(true); 47 | recyclerView.setLayoutManager(layoutManager); 48 | recyclerView.setItemAnimator(new DefaultItemAnimator()); 49 | recyclerView.setAdapter(mAdapter); 50 | } 51 | 52 | private void saveUserList() { 53 | RealmManager.createUserDao().save(DataGenerator.generateUserList()); 54 | } 55 | 56 | private void loadUserListAsync() { 57 | final RealmResults dataList = RealmManager.createUserDao().loadAllAsync(); 58 | dataList.addChangeListener(new RealmChangeListener() { 59 | @Override 60 | public void onChange() { 61 | updateRecyclerView(dataList); 62 | } 63 | }); 64 | } 65 | 66 | private void updateRecyclerView(List userList) { 67 | if (mAdapter != null && userList != null) { 68 | mAdapter.setData(userList); 69 | mAdapter.notifyDataSetChanged(); 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /app/src/main/java/com/ls/realm/ui/adapter/RealmAdapter.java: -------------------------------------------------------------------------------- 1 | package com.ls.realm.ui.adapter; 2 | 3 | import android.support.annotation.NonNull; 4 | import android.support.v7.widget.RecyclerView; 5 | import android.view.LayoutInflater; 6 | import android.view.View; 7 | import android.view.ViewGroup; 8 | import android.widget.TextView; 9 | 10 | import com.ls.realm.R; 11 | import com.ls.realm.model.db.data.IViewType; 12 | import com.ls.realm.model.db.data.User; 13 | 14 | import java.util.ArrayList; 15 | import java.util.List; 16 | 17 | public class RealmAdapter extends RecyclerView.Adapter { 18 | 19 | private static final int ITEM_TYPE_USER = 1; 20 | 21 | private List mDataList; 22 | 23 | public RealmAdapter() { 24 | mDataList = new ArrayList<>(); 25 | } 26 | 27 | @Override 28 | public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 29 | switch (viewType) { 30 | case ITEM_TYPE_USER: 31 | View confessionView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_user, parent, false); 32 | return new UserViewHolder(confessionView); 33 | } 34 | 35 | return null; 36 | } 37 | 38 | @Override 39 | public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { 40 | if (getItemViewType(position) == ITEM_TYPE_USER) { 41 | initUser(holder, position); 42 | } 43 | } 44 | 45 | @Override 46 | public int getItemViewType(int position) { 47 | IViewType type = mDataList.get(position); 48 | if (type instanceof User) { 49 | return ITEM_TYPE_USER; 50 | } 51 | 52 | return 0; 53 | } 54 | 55 | @Override 56 | public int getItemCount() { 57 | return mDataList.size(); 58 | } 59 | 60 | public void setData(@NonNull List dataList) { 61 | mDataList.clear(); 62 | mDataList.addAll(dataList); 63 | } 64 | 65 | private void initUser(@NonNull RecyclerView.ViewHolder holder, int position) { 66 | UserViewHolder viewHolder = (UserViewHolder) holder; 67 | User user = (User) mDataList.get(position); 68 | 69 | viewHolder.txtFirstName.setText(user.getFirstName()); 70 | viewHolder.txtLastName.setText(user.getLastName()); 71 | viewHolder.txtAge.setText(String.format("%d yo", user.getAge())); 72 | viewHolder.txtEmail.setText(user.getEmail()); 73 | viewHolder.txtCount.setText(String.format("Contacts count: %d", user.getContactList().size())); 74 | } 75 | 76 | private static class UserViewHolder extends RecyclerView.ViewHolder { 77 | 78 | private TextView txtFirstName; 79 | private TextView txtLastName; 80 | private TextView txtAge; 81 | private TextView txtEmail; 82 | private TextView txtCount; 83 | 84 | public UserViewHolder(View v) { 85 | super(v); 86 | 87 | txtFirstName = (TextView) v.findViewById(R.id.txtFirstName); 88 | txtLastName = (TextView) v.findViewById(R.id.txtLastName); 89 | txtAge = (TextView) v.findViewById(R.id.txtAge); 90 | txtEmail = (TextView) v.findViewById(R.id.txtEmail); 91 | txtCount = (TextView) v.findViewById(R.id.txtContactsCount); 92 | } 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /app/src/main/res/layout/ac_home.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /app/src/main/res/layout/item_user.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | 14 | 15 | 22 | 23 | 30 | 31 | 38 | 39 | 46 | 47 | 53 | 54 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lemberg/android-realm-sample/2066f716a91e32db58696068c6b838e91bef9905/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lemberg/android-realm-sample/2066f716a91e32db58696068c6b838e91bef9905/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lemberg/android-realm-sample/2066f716a91e32db58696068c6b838e91bef9905/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lemberg/android-realm-sample/2066f716a91e32db58696068c6b838e91bef9905/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lemberg/android-realm-sample/2066f716a91e32db58696068c6b838e91bef9905/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/values-v21/styles.xml: -------------------------------------------------------------------------------- 1 | > 2 | 3 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/values-w820dp/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 64dp 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #CE636F 4 | #AF5662 5 | #CE636F 6 | 7 | #F0F1F3 8 | #CFCFCF 9 | #A0A0A1 10 | #606060 11 | #ff4b4b4b 12 | #424242 13 | #ff3c3c3c 14 | 15 | 16 | -------------------------------------------------------------------------------- /app/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16dp 4 | 16dp 5 | 16dp 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | RealmSample 3 | 4 | -------------------------------------------------------------------------------- /app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | 13 | 14 |