Headertab

Drop Down MenusCSS Drop Down MenuPure CSS Dropdown Menu

Friday, 27 May 2016

Realm CRUD in Android


Hello friends

What is Realm ?


Realm is another type of database in Android. But, what is very important, Realm doesn’t use SQLite.
 If you use ORMLite or ActiveAndroid or any other similar library, your data is stored in SQLite database, because these libraries give us only an overlay on SQLite. With Realm there is no SQLite at all. Thanks to that Realm is very fast and you are even allowed to write the data in UI thread (mostly).

or


Realm is the mobile database solution that  proposed as  a replacement for SQLite & Core Data.

It’s like using SQLite with an ORM (as those who used SQLAlchemy may have experience), with a lot of awesome and convenient methods for data transactions.

However, Realm is NOT built on top of SQLite. It persists on its own persistence engine.

Realm is  also cross-platform that supports both iOS and Android, so developers who write Java, Swift, Objective-C can share the same Realm files painlessly.




Gradle

Add the following line to your dependencies.

dependencies {
    compile 'io.realm:realm-android:0.87.4'
    //other dependencies
}

or

download lib

you can download a realm-VERSION.jar and add it into app/libs.

Advantage 

Realm is said to be lightweight and fast compared to traditional solutions, like using SQLite and a fully-fledged ORM.

Bundling Realm into your app saves space and is capable of doing pretty much the same thing.

IMHO, the simplicity and minimalistic nature of Realm is its biggest advantage, but also its limitation over other solutions at the same time.

An easy way to perform queries and transactions asynchronously.

All fetches (including queries) are lazy in Realm.  

An easy way to build queries (just call existing Realm methods).

Possibility to run the Realm database in-Memory.

Possibility to use Realm objects across threads.

Realm supports advanced features like Encryption,graph queries, and easy migrations. Our APIs are a great fit to build seamless reactive apps, and we provide easy add-ons to build complex UIs with ease.

Disadvantage 

ID for objects cannot be automatically generated

You can have only getter and setter methods in a class. This means you cannot override the methods

Getter and Setter Restrictions

Due to how the proxy classes override getters and setters in the model classes, there are some restrictions to what is allowed in a model class:

public class Person extends RealmObject {
    private String name;
    private int age;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
}

Only private instance fields

Only default getter and setter methods

Static fields, both public and private 

Static methods

Implementing interfaces with no methods

So you can not extend anything else than RealmObject or to override methods like toString() or equals().

Not supporting null values

You can not store null as a value for primitive data types (booleans, integers, floating-point numbers, dates, and strings). You will need an extra boolean field to capture if a field is null or not.


Overall


Generally speaking, Realm is a reliable mobile database solution.
Realm works as advertised, but Realm is still a rapidly growing and evolving project. Be sure to follow the latest release , some problems that requires tens line of custom code before might be handled for you by Realm with a single method (e.g. storing an array of object into Realm, update existing record instead of inserting new record when applicable).
Realm for the Cocoa framework and Realm for Java are both available on GitHub under the Apache 2.0 license.

Resources 

Official Site for Realm
https://realm.io/

Realm Full API for Java
http://realm.io/docs/java/latest/api/

Realm Browser
To inspect your ream data. Only available on Mac OS X till now (May 2015)
If you are interested, it’s inside tools/RealmBrowser in the Realm GitHub repository.



Now see simple example step by step..

Step 1 :-

Create a new Android project

Step 2 :-

if you use android studio then add dependency Realm lib

dependencies {
    compile 'io.realm:realm-android:0.87.4'
    //other dependencies
}

Step 3:-

Create a Application class and Initialize Realm:

MyApplication.java

package com.samset.realmdatabaseexample;

import android.app.Application;

import io.realm.Realm;
import io.realm.RealmConfiguration;

/**
 * Created by samset on 27/05/16.
 */
public class MyApplication extends Application {
   
   private RealmConfiguration config;
   @Override
    public void onCreate() {
        super.onCreate();
      
    // Initialize Realm
       config = new RealmConfiguration.Builder(this).build();
       Realm.setDefaultConfiguration(config);
    }

}


Step 4:-

Create model class or Realm object 

package com.samset.realmdatabaseexample.model;

import io.realm.RealmObject;
import io.realm.annotations.PrimaryKey;
import io.realm.annotations.Required;

/**
 * Created by samset on 27/05/16.
 */
public class Person extends RealmObject {

// Realm db use a annotation
    @PrimaryKey
    private long id;
    @Required
    private String fname;
    @Required
    private String lname;
    @Required
    private String contact;

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getFname() {
        return fname;
    }

    public void setFname(String fname) {
        this.fname = fname;
    }

    public String getLname() {
        return lname;
    }

    public void setLname(String lname) {
        this.lname = lname;
    }

    public String getContact() {
        return contact;
    }

    public void setContact(String contact) {
        this.contact = contact;
    }
}


Step 5:-

Now you initialize Realm in your main activity


package com.samset.realmdatabaseexample;

import android.app.ProgressDialog;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.AppCompatButton;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.TextView;
import android.widget.Toast;

import com.samset.realmdatabaseexample.adapter.ListdataAdapter;
import com.samset.realmdatabaseexample.controller.PrimaryKeyFactory;
import com.samset.realmdatabaseexample.controller.RealmController;
import com.samset.realmdatabaseexample.model.Person;

import java.util.List;

import io.realm.Realm;

public class MainActivity extends AppCompatActivity {

    private Realm realm;

    private EditText fname, lname, contactno;
    private AppCompatButton btncreate,btnget;
    private RealmController realmController;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //initialize realm 
        realm = Realm.getDefaultInstance();
        realmController=new RealmController(realm);
        PrimaryKeyFactory.getInstance().initialize(realm);
        setView();

    }


    private void setView() {

        fname=(EditText)findViewById(R.id.input_fname);
        lname=(EditText)findViewById(R.id.input_lname);
        contactno=(EditText)findViewById(R.id.input_contact);
        btncreate=(AppCompatButton) findViewById(R.id.btn_signup);
        btnget=(AppCompatButton) findViewById(R.id.btn_get);

        btncreate.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                signup();
            }
        });
        btnget.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                startActivity(new Intent(MainActivity.this,ResultActvity.class));


            }
        });
    }

    private void signup()
    {
        if (!validate())
        {
           onSignupFailed();
            return;
        }

        btncreate.setEnabled(false);

        final ProgressDialog progressDialog = new ProgressDialog(MainActivity.this,
                R.style.AppTheme_Dark_Dialog);
        progressDialog.setIndeterminate(true);
        progressDialog.setMessage("Creating Account...");
        progressDialog.show();

        new android.os.Handler().postDelayed(
                new Runnable() {
                    public void run() {
                        // On complete call either onSignupSuccess or onSignupFailed
                        // depending on success
                       
onSignupSuccess();
                        // onSignupFailed();
                       
progressDialog.dismiss();
                    }
                }, 3000);
    }

    public void onSignupSuccess() {
        btncreate.setEnabled(true);
        String strfname = fname.getText().toString();
        String strlname = lname.getText().toString();
        String strcontact = contactno.getText().toString();

       // add data in Realm database
        realmController.addData(strfname,strlname,strcontact);
        Log.e("Main"," Success");
        setResult(RESULT_OK, null);

       fname.setText("");
      lname.setText("");
      contactno.setText("");
    }

    public void onSignupFailed() {
        Toast.makeText(getBaseContext(), "Login failed", Toast.LENGTH_LONG).show();

        btncreate.setEnabled(true);
    }
    public boolean validate() {
        boolean valid = true;

        String name = fname.getText().toString();
        String lanme = lname.getText().toString();
        String contact = contactno.getText().toString();

        if (name.isEmpty() || name.length() < 3) {
            fname.setError("at least 3 characters");
            valid = false;
        } else {
            fname.setError(null);
        }

        if (lanme.isEmpty() || lname.length() < 3) {
            lname.setError("Enter last name");
            valid = false;
        } else {
            lname.setError(null);
        }

        if (contact.isEmpty() || contact.length() < 10 || contact.length() > 10) {
            contactno.setError("Enter valid no.");
            valid = false;
        } else {
            contactno.setError(null);
        }

        return valid;
    }
}


Step 6:-

Now create a controller class by name RealmController


package com.samset.realmdatabaseexample.controller;

import android.util.Log;

import com.samset.realmdatabaseexample.model.Person;

import java.util.ArrayList;
import java.util.List;

import io.realm.Realm;
import io.realm.RealmResults;

/**
 * Created by samset on 27/05/16.
 */
public class RealmController {

    Realm realm;

    public RealmController(Realm rl)
    {
        this.realm=rl;
    }


// add data method in Realm
    public void addData(String fname,String lname,String contact)
    {
      //  Log.e("Controller"," Primary key "+getprimary());
        
realm.beginTransaction();
//this class generate auto increment id because Realm database does not supported auto increment primary key
        long i= PrimaryKeyFactory.getInstance().nextKey(Person.class);
        Person person=realm.createObject(Person.class);
        person.setId(i);
        person.setFname(fname);
        person.setLname(lname);
        person.setContact(contact);
        realm.commitTransaction();

        Log.e("Controller"," key "+i);

    }

    public List<Person> getAllData()
    {
        List<Person> resultdata=new ArrayList<>();
        realm.beginTransaction();
        RealmResults<Person> results=realm.where(Person.class).findAll();

        for (int i=0;i<results.size();i++)
        {
            Person person=new Person();
            person.setFname(results.get(i).getFname());
            person.setLname(results.get(i).getLname());
            person.setContact(results.get(i).getContact());

            resultdata.add(person);
        }

        Log.e("Controller"," all data "+resultdata.size());

        return resultdata;
    }

}

Step 7:-

Now create a auto increment id class PrimaryKeyFactory this class return increment id


package com.samset.realmdatabaseexample.controller;
import android.util.Log;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicLong;
import io.realm.Realm;
import io.realm.RealmConfiguration;
import io.realm.RealmObject;
import io.realm.RealmObjectSchema;
import io.realm.RealmSchema;

import static java.lang.String.format;
/**
 * Created by samset on 27/05/16.
 */
public class PrimaryKeyFactory {


    /** primary key field name */
   
private static final String PRIMARY_KEY_FIELD = "id";

    /**
     * Singleton instance.
     */
   
private final static PrimaryKeyFactory instance = new PrimaryKeyFactory();

    /**
     * Maximum primary key values.
     */
   
private Map<Class<? extends RealmObject>, AtomicLong> keys;

    /**
     * get the singleton instance
     *
@return singleton instance
     */
   
public static PrimaryKeyFactory getInstance() {
        return instance;
    }

    /**
     * Initialize the factory. Must be called before any primary key is generated
     * - preferably from application class.
     */
   
public synchronized void initialize(final Realm realm) {
        if (keys != null) {
            throw new IllegalStateException("already initialized");
        }
        // keys field is used as an initialization flag at the same time
       
keys = new HashMap<>();
        final RealmConfiguration configuration = realm.getConfiguration();
        final RealmSchema realmSchema = realm.getSchema();
        //using RealmConfiguration#getRealmObjectClasses because
        // RealmSchema#getAll() returns RealmObjectSchema with simple class names only
       
for (final Class<? extends RealmObject> c : configuration.getRealmObjectClasses()) {

            final RealmObjectSchema objectSchema = realmSchema.get(c.getSimpleName());
            Log.i(getClass().getSimpleName(), format("schema for class %s : %s", c.getName(), objectSchema));
            if (objectSchema != null && objectSchema.hasPrimaryKey()) {
                Number keyValue = null;
                try {
                    keyValue = realm.where(c).max(PRIMARY_KEY_FIELD);
                } catch (ArrayIndexOutOfBoundsException ex) {
                    Log.d(getClass().getSimpleName(), format("error while getting number primary key %s " +
                            " for %s",PRIMARY_KEY_FIELD, c.getName()), ex);
                }
                if (keyValue == null) {
                    Log.w(getClass().getSimpleName(), format("can't find number primary key %s " +
                            " for %s.",PRIMARY_KEY_FIELD, c.getName()));
                } else {
                    keys.put(c, new AtomicLong(keyValue.longValue()));
                }
            }
        }
    }

    /**
     *  Automatically create next key for a given class.
     */
   
public synchronized long nextKey(final Class<? extends RealmObject> clazz) {
        if (keys == null) {
            throw new IllegalStateException("not initialized yet");
        }
        AtomicLong l = keys.get(clazz);
        if (l == null) {
            Log.i(getClass().getSimpleName(), "There was no primary keys for " + clazz.getName());
            //RealmConfiguration#getRealmObjectClasses() returns only classes with existing instances
            //so we need to store value for the first instance created
           
l = new AtomicLong(0);
            keys.put(clazz, l);
        }
        return l.incrementAndGet();
    }
}

Thank you

I hope this blog very helps you if you like this blog please share and like this page.

Full Sorce codeRealmDatabaseSample


Live Sample