When our app has data that needs to be saved to the local cache, you can use File,sharedpreferences, as well as SQLite.
Sharedpreferences actually stores data of the basic data type in the form of key-value pairs, using XML. For a complex filter query
operation, file and sharedpreferences are not satisfied. SQLite can accommodate cached data operations with a large number of complex query requirements. However, the use of SQLite is slightly more complex, the code is very large, fortunately there are many excellent online ORM framework can be used, analogy Ormlite,greendao and so on.
Ormlite,greendao These frameworks are the ORM Object Relational mapping framework encapsulated on sqlite basis, simplifying the operation of code.
And today's protagonist: Realm is a lightweight database that can replace SQLite and ORM libraries.
Faster than Sqlite,realm and has many modern database features, such as support for JSON, streaming APIs, data change notifications, and encryption support, are all handy for Android developers. Not much introduction, more detailed introduction See Official website: https://realm.io/
Let's focus on the use of Reaml and see where it's really cool.
Environment configuration:
1. Add dependencies to the Build.gradle file in project:
dependencies { ... Classpath "io.realm:realm-gradle-plugin:1.1.0" ... }
2. Add the following code to the top of the app module's Build.gradle file:
Apply plugin: ' com.android.application ' Apply plugin: ' realm-android ' ....
Configuration is complete.
Use:
In the whole process of using realm as the protagonist, let's take a look at a translation in the Realm class:
The/** * Realm class can store and manage your persisted objects, and can be used to create realmobjects instances. Objects within a domain can be queried and read at any time. * Create, modify and delete operations must be included in a complete transaction, followed by the code. * The transaction ensures that multiple instances (across multiple threads) can access the same object in a consistent state and with the assurance that the transaction is in acid-based condition. * * When a realm instance operation is complete, remember to call the Close () method. Doing so will cause the local resource to fail to release, causing Oom. * * Realm instances cannot access operations between different threads. To be exact, you must open an instance on each thread you want to use * each thread uses a reference count to automatically cache the realm instance, so as long as the reference count does not reach 0, the call getinstance (Realmconfiguration) method returns the cached Rea The LM instance should be considered a lightweight operation. * * For UI threads, open and close realm instances should be placed in the Oncreate/ondestroy or Onstart/onstop method * * Between different threads, the realm instance uses the handler mechanism to adjust his state. In other words, if there is no looper in the realm instance, the update notification cannot be received, * unless the Waitforchange () method is called manually * * A standard mode of work in the Android activity field can be seen below * in an In the droid activity, realm's standard working mode is as follows: * * * public class Realmapplication extends application {* * \ @Ov Erride * public void OnCreate () {* Super.oncreate (); * *//The Realm file is located in the "Files" directory. * Realmconfiguration realmconfig = new REALMCOnfiguration. Builder (This). Build (); * Realm.setdefaultconfiguration (Realmconfig); *} *} * * public class Realmactivity extends Activity {* * Private realm realm; * * \ @Override * protected void OnCreate (Bundle savedinstancestate) {* Super.oncreate (savedinstancest ATE); * Setcontentview (R.layout.layout_main); * Realm = Realm.getdefaultinstance (); *} * * \ @Override * protected void OnDestroy () {* Super.ondestroy (); * Realm.close (); *} *} * * * Realm supports string and byte field lengths up to 16MB * Reference connection: * <a href= "Http://en.wikipedia.org/wiki/AC ID ">ACID</a> * <a href=" https://github.com/realm/realm-java/tree/master/examples ">examples using realm</a> * * * *
Part of the source code analysis:
public final class Realm extends Baserealm {//default file name, what is it? public static final String Default_realm_name = realmconfiguration.default_realm_name;//How so familiar? Is Rxjava? @Override @OptionalAPI (dependencies = {"Rx. Observable "}) public observable<realm> asobservable () {return configuration.getrxfactory (). from (this); }//The following methods should be the name of the public <e extends realmmodel> void Createallfromjson (class<e> clazz, Jsonarray json) {} Public <e extends realmmodel> void Createorupdateallfromjson (class<e> clazz, Jsonarray JSON) {} public &L T E extends realmmodel> e Createorupdateobjectfromjson (class<e> clazz, Jsonobject JSON) {} public <e extends Realmmodel> e CreateObject (Class<e> clazz) {} public <e extends Realmmodel> e copytorealmorupdate (e obje CT) {} public void Executetransaction (Transaction Transaction) {} public void Delete (class<? extends REALMMODEL&G T clazz) {}}
Description of the Realmconfiguration class translation:
/** * A Realmconfiguration object that can be used to set a specific realm instance * Realmconfiguration instances can only be passed through the Io.realm.RealmConfiguration.Builder class's Build ( ) method to create a * to use the default Realmconfiguration instance, use the Io.realm.realm#getdefaultinstance () method. * Call Realm#setdefaultconfiguration (realmconfiguration) * <p> * If you want to use a realm instance of your own Realmconfiguration instance to configure it You can create an instance of the simplest configuration with the following code: * realmconfiguration config = new Realmconfiguration.builder (GetContext ()). Build ()) * This creates an instance, With properties: * * <ul> * <li>realm's default filename is "Default.realm" </li> * <li> "Default.realm" File saved in " Context.getfilesdir () "Directory </li> * <li> Its schema version number is set to 0</li> * </ul> */
Part of the source code analysis:
Public final class Realmconfiguration {//default file name public static final String default_realm_name = "Default.realm";// Rx Factory Private Final rxobservablefactory rxobservablefactory;//weak reference private final weakreference<context> contextweakref;/** * * Returns the realm file name from the asset directory and can also be saved in asset? * @return input stream to the asset file. * @throws IOException If copying the file fails. */InputStream Getassetfile () throws IOException {Context context = Contextweakref.get (); if (context! = null) {return context.getassets (). open (Assetfilepath); } else {}}/** * uses the app's own internal drive directory to store the realm file. No extended access rights are required. * The default directory is:/data/data/<packagename>/files, the path can be modified depending on the specific implementation of the vendor * * @param parameter context please use the application conte Xt. */Public Builder (context context) {if (context = = null) {throw new Illegalargumentexce Ption ("A non-null Context must be provided"); } REALMCOre.loadlibrary (context); Initializebuilder (Context.getfilesdir ()); }}
Through the above translation instructions and source analysis, you should almost understand the principle of realm and basic use of it. Summarize the following points:
1, the realm saves the result is actually in a file, the default filename is "Default.realm", in "Context.getfilesdir ()" The directory, namely:/data/data/<packagename>/ Files/default.realm. This means that when you "erase" the current app in app management, the data in the realm database is lost. Therefore, we need to put the default data files in the asset directory, and then copy to "Context.getfilesdir ()" When the database is initialized.
2. When creating a Realmconfiguration object, you can specify the initialized database file by using the. Assetfile (this, "realm file path in assets") method. Realm will copy the Xxx.realm file under the development path to the Context.getfilesdir () directory to replace the empty database file created by default.
3, you can set the default file name, through the Realmconfiguration class to configure. The path does not seem to change and needs to be seen by the specific device vendor.
4, the realm instance needs to obtain in each time the concrete operation, may consider is a data operation Sessin, must close after the use finishes.
Open and close realm instances should be placed in the Oncreate/ondestroy or Onstart/onstop method.
5, Realm seems to have Rxjava shadow, support chain-type asynchronous task?
6, Realm has a variety of additions and deletions to change the method, you can also instantiate a realmobject subclass Java Bean based on JSON data.
7, Focus: Remember, the Realm database primary key field is not automatically grow, need to set their own, do add when the ID field value is not given, the default is 0. Add an error later, saying that the data with ID 0 already exists. Especially when adding in batches, beware of the tragedy that only adds a record.
8, data Update automatically. Mrealm.addchangelistener (this);//The system callback this method when the data for the database has changed.
After the above analysis and summary, in fact, it is very clear. For those who reach out, simply make some code. There are some areas to be aware of, which are explained in the code.
Application code:
public class MyApplication extends application { private String realmname = "Dk.realm"; @Override public void OnCreate () { super.oncreate (); Realmconfiguration realmconfig = new Realmconfiguration.builder (this) . Name (realmname) //.assetfile (This, " Realm file path in Assets,will copy this file to Context.getfilesdir () replace an empty realm file ") . Build (); Realm.setdefaultconfiguration (Realmconfig); }}
Java Bean:
public class TestUser extends Realmobject { @PrimaryKey private int userid;//id, primary key @Required Private String username;//user name, required field private string userpwd;//password private int userage;//age private String useraddress;//address private string userwork;//work private string usersex;//sex //private realmlist<e> list; Set//...}
Basedao, simple package, the basic additions and deletions to the function extraction:
public class Basedao {private Realm realm; Public Basedao (Realm realm) {This.realm = realm; }/** * Added (performance is better than Saveorupdate () method below) * * @param object * @return Save or modify Success */public Boolean INS ERT (Realmobject object) {try {realm.begintransaction (); Realm.insert (object); Realm.committransaction (); return true; } catch (Exception e) {e.printstacktrace (); Realm.canceltransaction (); return false; }}/** * Added (performance is better than the following Saveorupdatebatch () method) * * @param list * @return Batch Save Success */public Boolean I Nsert (list<? extends realmobject> List) {try {realm.begintransaction (); Realm.insert (list); Realm.committransaction (); return true; } catch (Exception e) {e.printstacktrace (); Realm.canceltransaction (); return false; } }//...}
Userdao extends Basedao:
/** * Single Save Demo */public boolean addonetest () {Boolean BL = false; try{realm.begintransaction (); Create an object in the database, the primary key default value is 0 TestUser user = Realm.createobject (testuser.class);//(class, PRIMARY key)//update the values of the respective segments of the database User.setusername ("admin"); The value of the primary key field is updated from 0 to 55. Instead of directly creating an object with an ID of 55 user.setuserid (55); ... realm.committransaction (); BL = true; }catch (Exception e) {e.printstacktrace (); Realm.canceltransaction (); }/*try{realm.begintransaction (); TestUser user2 = new TestUser ("Hibrid", "120250", 26, "Ganzhou", "thief", "male"); Do not give ID, will default to 0//user2.setuserid (102); TestUser Userwithid = Realm.copytorealm (user2); Realm.committransaction (); BL = true; }catch (Exception e) {e.printstacktrace (); Realm.canceltransaction (); }*/return bL }//init Data public boolean init () {/** * Note here that the method that was last called is the Add or modify method. * If the list's data is not given an ID, then the first record is added with a successful ID of 0, after which it is modified on this basis. * The last effect is that the database has only one record, the ID is 0, the other fields are updated for the last object's data */list<testuser> List = new arraylist<> (); List.add (New TestUser (0, "Android", "123123", 20, "Changde, Henan", "Chuan Cai", "female")); List.add (New TestUser (1, "Angel", "13588889988", 21, "Yunnan Xishuangbanna", "Pilot", "male")); List.add (New TestUser (2, "Adidass", "110119", 28, "Yunnan Texas", "Seaman", "male")); List.add (New TestUser (3, "hijack", "250250", 39, "California Power Plant", "Chef", "female")); List.add (New TestUser (4, "Hibrid", "120250", 26, "Ganzhou", "thief", "male")); List.add (New TestUser (5, "admin", "123456", 20, "Hubei Seoul", "programmer", "female")); return Saveorupdatebatch (list); }/** * Conditional Query * * @return return result set */public realmresults<testuser> findbyanyparams (hashmap<object , object> params) {//realm.where (Testuser.class)//Can be followed by query conditions//.or () or//.beginswith () with XXX opening//.endswith () with XXX end//.greaterthan ( ) greater than//.greaterthanorequalto () is greater than or equal to//.lessthan () less than//.lessthanorequa LTo () Less than or equal to//.equalto () equals//.notequalto () not equal to//.findall () Query all//.average () averages//.begingroup () Start grouping//.endgroup () End group//.between () between A and B//.contains () contains xxx//.count () Statistics//.distinct () de-duplication//.findfirst () returns the first row of records for the result set//.ISN Otempty () non-empty string//.isempty () is an empty string//.isnotnull () non-empty object//.isnu LL () is an empty object//.max () maximum//.maximumdate () Maximum date//.min ( ) MinimumValue//.minimumdate () Minimum date//.sum () sum return Realm.where (testuser.class ). FindAll (); }
Mainactivity Code:
@Override protected void onCreate (Bundle savedinstancestate) { super.oncreate (savedinstancestate); Setcontentview (r.layout.activity_main); Mrealm = Realm.getdefaultinstance (); Userdao = new Userdao (Mrealm); //... /** * Database Data Update monitor * /Mrealm.addchangelistener (this); } ... @Override public void OnChange (Realm element) { findAll (); } @Override protected void OnDestroy () { Userdao = null; Mrealm.close (); Super.ondestroy (); }
Adding and deleting the code to pay attention to the transaction, the others are simple.
Sorry, forgot to upload the demo. Need to demo, please leave QQ, send your mail.
Android Realm Database Perfect parsing