Kotlin - Android

Integration of Anko Sqlite database in Kotlin Android

Anko is the SQLite database wrapper for Android in Kotlin. As we have used many best SQLite database wrapper in android java library. For example, we have practiced with Green Dao, Active Android, and ORMLite. I would recommend to please check those wrappers if you still using Java for Android development. These wrappers are still good for Android application development in Java.  Here is written the post for Green Dao fast ORM and Active Android database wrapper.

If you are looking to build a small application which is required local database then I would be recommended to use Active Android best wrapper for that. It makes your development fast. But if the application is major used database to frequent sync with the server then Green Dao wrapper is the best suit for this.

Anko is the kotlin library for android SQLite database for better, easier and faster Android development. As everybody familiar with Kotlin that is the new language for Android development. I have explained the basic of Kotlin to get started in Android in my last posts. If you are planning to quick start Kotlin then these post might help you to better understand. Here are the posts Basic of Kotlin to get started in Android part -1, part -2, part -3 and part-4. Great 🙂

If you looking for how to sync and fetch data with the server then I have explained in my last post to API call by using Retrofit in Kotlin with RxJava and Rx Android. I hope it will help you a lot to better understand.

Ok, Let’s focus on Anko SQLite database wrapper. In this tutorial, we will learn how to integrate Anko – SQLite database in Android? As we know that today design pattern is best practice to build any android application. We used some of the popular design patterns like MVP and MVVM with a Reactive feature. Anko SQLite is much comfortable with Reactive and best design pattern. So we will integrate the Anko – SQLite database wrapper with MVP design pattern with RxJava and RxAndroid. First of all, we need to add below library dependency in build.gradle file in app level.

    // Anko for SQLite anko_version = '0.9.1'
    compile "org.jetbrains.anko:anko-sqlite:$anko_version"

    // RX rxjava2_version = '2.0.1'
    compile "io.reactivex.rxjava2:rxjava:$rxjava2_version"
    compile "io.reactivex.rxjava2:rxandroid:$rxjava2_version"

Anko – SQLite provides the ManagedSQLiteOpenHelper class which extends the SQLiteOpenHelper class. ManagedSQLiteOpenHelper provides to create blocks of code where you will execute the database operations. Let me create the DbHelper class which extends the ManagedSQLiteOpenHelper for creating the Database table and schema.

class DbHelper(var context : Context = MainApplication.instance) : ManagedSQLiteOpenHelper(context, DB_NAME, null, DB_VERSION){

    override fun onCreate(db: SQLiteDatabase?) {
       // TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
        db!!.createTable(FriendsTable.TABLE_NAME, true, FriendsTable.ID to INTEGER + PRIMARY_KEY + AUTOINCREMENT, FriendsTable.FRIEND_ID to TEXT  ,
                FriendsTable.NAME to TEXT, FriendsTable.EMAIL to TEXT
                )
    }

    override fun onUpgrade(db: SQLiteDatabase?, oldVersion: Int, newVersion: Int) {
        TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
    }

    companion object {
        @JvmField
        val DB_VERSION = 1
        @JvmField
        val DB_NAME = "dbFriends"
    }
}

Ok before going to next steps, You need to know that what am I trying to do here? Actually, I have data on the server, I need to fetch those data from server. Once I fetched those data I want to store into DB and fetch from DB to show on view. And I want to delete data from the database table. For all those operations I need to create the DBSoruce interface in Kotlin.

interface DbSource {

    fun saveFriendsList(friends: Friends.User)

    fun loadFriends() : Observable<List<Friends.User>>

    fun detailFriend(friendsId : String) : Observable<Friends.User>

    fun deleteFriend(friends: Friends.User) : Observable<Boolean>
}

Ok, Now I need to implement this DbSource for DBManager.

class DbManager(var dbHelper: DbHelper = DbHelper(MainApplication.instance)):  DbSource{

    override fun detailFriend(friendsId: String): Observable<Friends.User> {
        var user : Friends.User? = null
        dbHelper.use {
            select(FriendsTable.TABLE_NAME)
                    .whereSimple("${FriendsTable.FRIEND_ID} = ?", friendsId)
                    .parseOpt(object : MapRowParser<Friends.User> {
                        override fun parseRow(columns: Map<String, Any?>): Friends.User {

                                val id = columns.getValue("friend_id")
                                val name = columns.getValue("name")
                                val email = columns.getValue("email")
                                user = Friends.User(id = id.toString(), name = name.toString(), email = email.toString())

                              return user!!
                        }
                    })
        }
        return Observable.just(user)
    }


    override fun deleteFriend(friends: Friends.User): Observable<Boolean> {
       var isDeleted : Boolean? = null
       dbHelper.use {
                try {
                    beginTransaction()
                    val result = delete(FriendsTable.TABLE_NAME, "${FriendsTable.FRIEND_ID} = {friend_id}", "friend_id" to friends.id!!) > 0

                    if (result) {
                        setTransactionSuccessful()
                        isDeleted = true
                    } else {
                        isDeleted = false
                    }

                } catch (e : Throwable) {
                    Timber.e(e)
                    isDeleted = true

                } finally {
                    endTransaction()
                }
            }
       return Observable.just(isDeleted)
    }

    override fun loadFriends(): Observable<List<Friends.User>> {
        var listFrindsUser = ArrayList<Friends.User>()
        dbHelper.use {
            select(FriendsTable.TABLE_NAME).parseList(object : MapRowParser<List<Friends.User>> {

                override fun parseRow(columns : Map<String, Any?>) : ArrayList<Friends.User> {

                    val id = columns.getValue("friend_id")
                    val name = columns.getValue("name")
                    val email = columns.getValue("email")
                    val users = Friends.User(id = id.toString(), name = name.toString(), email = email.toString())
                    listFrindsUser.add(users)

                    return listFrindsUser
                }
            })
        }
        return Observable.just(listFrindsUser)
    }

    override fun saveFriendsList(friends: Friends.User){
            try {
                val context = dbHelper.context
                insertPost(context, friends)

            } catch (e : Throwable) {
                Timber.e(e)
            }
    }

    private fun insertPost(context: Context, friends: Friends.User) : Boolean = dbHelper.use {
        try {
            beginTransaction()
            val insertedId = insert(FriendsTable.TABLE_NAME, FriendsTable.FRIEND_ID to friends.id, FriendsTable.NAME to friends.name, FriendsTable.EMAIL to friends.email)

            if (insertedId != -1L) {
                setTransactionSuccessful()
                true
            } else {
                false
                throw RuntimeException("Fail to insert")
            }

        } finally {
            endTransaction()
        }
    }

}

As in above program, we have seen that I am using one block to create any SQLite operation.

dbHelper.use {
           
        }

Ok Great 🙂 Now I need to fetch data from Database to show on View. Here I am using MVP design pattern then I will implemental all those model and businesses logic in the presenter class. Ok, How can I load the data from the database, and How can View those data and delete data from the database?

Load Data from the database table.

  override fun loadFriendsDb() {
        var observableFriends = DbManager().loadFriends();
        updateViewFromDb(observableFriends)
    }
 fun updateViewFromDb( observableFriends: Observable<List<Friends.User>>){
        var subscribe =  observableFriends.subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe({listUsers: List<Friends.User>? ->
                    view.onLoadFriendsOk(listUsers!!)
                   },
                        { t: Throwable? -> view.showEmptyView(true)})
        subscriptions.add(subscribe)
    }

View data from Database table.

 override fun loadUserDetail(userId: String) {
        var observableUser = DbManager().detailFriend(userId)
        var subscribe =  observableUser.subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe({user: Friends.User? ->
                    view.onLoadUserDetailOk(user!!)
                }, { t: Throwable? -> view.showLoadErrorMessage(t!!.message.toString())})
        subscriptions.add(subscribe)
    }

Delete data from the database table.

 override fun deleteItem(user: Friends.User) {
        var observableBoolean  = DbManager().deleteFriend(user)
        var subscribe = observableBoolean.subscribe ({t : Boolean -> view.deletedItem(t!!)},{t: Throwable -> view.showLoadErrorMessage(t.message!!)})
        subscriptions.add(subscribe)
    }

Here is the result.

Wrapping up: As we practiced that Anko SQLite database wrapper is very fast and easy to integrate into an Android application by using awesome new language Kotlin. Anko SQLite wrapper is the best wrapper or more than enough for fast Android development. You can play much more with this wrapper in your application. It will create quite good fun again for Android application development. To learn more in detail please check the official Anko site which is implemented by Jetbrain team.

Here is the GitHub Link of full source code.

Please do subscribe your email to get the updated newsletters from this blog and if you feel that this post will help you to understand then do not forget to share and comment below.

Happy Coding 🙂

0 0 votes
Article Rating

Recent Posts

Hide your production API key or any sensitive data in Android

Hi everyone, In this article, we are going to learn how to hide the production… Read More

2 years ago

How to handle the localisation or multi language support in android with examples?

Hello everyone, Today in this article, we are going to learn about localisation to support… Read More

2 years ago

How to convert any callback to Coroutines and use them in Kotlin Android?

Hello everyone, In this article, we are going to learn something to handle the callback… Read More

2 years ago

Request Permission Launcher with Kotlin in Android

In this article, we are learning about the run time permissions for request permission launchers.… Read More

2 years ago

Implement the SMS User Consent API and SMS Retriever API in Android

Hello everyone. In my last tutorial, we learned about the Jetpack Compose introduction and about applying the… Read More

3 years ago

Jetpack Compose Coroutine flow with LiveData/ViewModel in Android

Hello everyone, In this article, we are going to learn about the Jetpack Compose with… Read More

3 years ago