Kotlin Elvis Operator (?:) Example

The Elvis Operator (?:) is represented by a question mark followed by a colon: ?: .It is ?: is a binary operator. If the first operand is not null, it is returned. Otherwise the value of the second operand (which may be null) is returned and it can be used with this syntax:
first operand ?: second operand

Lets take example:
If the expression to the left of ?:  (here : b?.length) is not null, the elvis operator returns it (here: result of expression b.length), otherwise it returns the expression to the right (here: -1). Note that the right-hand side expression is evaluated only if the left-hand side is null.
var b: String? = "Some Nullable String Value"
val l = b?.length ?: -1
When we have a nullable reference r, we can say "if r is not null, use it, otherwise use some non-null value x"
Above Elvis operator expression written with ?:: can be expressed along with the complete if-expression as below:
val l: Int = if (b != null) b.length else -1

Things to Note
Note that, since throw and return are expressions in Kotlin, they can also be used on the right hand side of the elvis operator. This can be very handy, for example, for checking function arguments:

​fun foo(node: Node): String? {
    val parent = node.getParent() ?: return null
    val name = node.getName() ?: throw IllegalArgumentException("name expected")
    // ...
}

Val and Var in Kotlin

Read-only local variables are defined using the keyword val. They can be assigned a value only once. val use to declare final variable.

val in Kotlin
val is same as the final keyword in java. As you should probably know that we cannot reassign value to a final variable but can change its properties. Similarly, val is like Final variable and its known as immutable in kotlin and can be initialized only single time.
Characteristics of val variables in Kotlin:
1. Initialization of val in Kotlin
1.1 Immediate assignment
val a: Int = 1
val b = 2   // `Int` type is inferred
1.2 deferred assignment
val c: Int  // Type required when no initializer is provided
c = 3       // deferred assignment
1.3 Must be initialized
Refer more about https://kotlinlang.org/docs/reference/basic-syntax.html#defining-variables
1.4 value can not be changed or reassign
1.5 val is same as the final modifier in java. can not assign to a final variable again but can change its properties.
Uses: val is used for getter (read-only, value won't change).
Extra:
val variables are not necessarily immutable. They are final -- only the reference is immutable -- but if the object stored in the val is mutable, the object is mutable regardless of whether it is assigned via val or var.

Var in Kotlin:
var in kotlin used to declare a variable which is like general variable and its known as a mutable variable in kotlin and
If you use the var keyword to declare Variables that can be reassigned (assigned multiple times)

Characteristics of var variables in Kotlin:
1. variables defined with var are mutable(Read and Write)
2. We can initialize later by using lateinit modifier [lateinit also use for global variable we can not use it for local variable]  value can be changed or reassign but not in global scope

var is as a general variable

Uses:
1. use var where value is changing frequently
2. var is used for setter (value will change).

Difference
val is immutable and var is mutable in Kotlin.

Example:

package com.example.espl.val_vs_var_in_kotlin

import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.util.Log

class MainActivity : AppCompatActivity() {

    val a: Int = 1  // immediate assignment
    val b = 2   // `Int` type is inferred

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val c: Int  // Type required when no initializer is provided
//        Log.e("IntVal",""+c)  //  Warning: Variable 'c' must be initialised
        c = 3  // deferred assignment
        Log.e("val c",":: "+c)

        val person=Person("Ram", 50, Address("kaka ni pol","New street", "Ahmedabad"))

        Log.e("Value of city of person","- City:: "+person.address.city)
//        person.address.city="Rajkot"; // Val cannot be reassigned
        person.address.street="Dalal street"; // Var street can be reassigned
        person.address.name="Maharshi"; // Val name can be reassigned

        Log.e("log of val person","after change of address name,street :: "+person.toString()) //

        val person1=Person("Raj", 50, Address("Raj street name","Raj street", "Rajkot"))
//        person=person1           // Warning: Val person cannot be reassigned
//        person=Person("Lakhan", 52, Address("kaka ni pol","New street", "Ahmedabad")) // Warning: Val person cannot be reassigned

        person.address=person1.address // we can reassign the address of a val person as its variable
        // This proves that val cannot be reassigned but its properties defined using the val can be changed.

//val is used for getter (read-only, value won't change).
//        person.age=person1.age // Warning: Val age cannot be reassigned
//        person.age=51 // Warning: Val age cannot be reassigned

//var is used for setter (value will change).
        person.name="Tarun"
        Log.e("log of val person","after change of var address :: "+person.toString()) //
    }

    data class Person(var name: String, val age: Int,var address: Address)

    data class Address(var name : String, var street : String, val city : String)

//    OutPut
    //04-24 12:30:36.338 5104-5104/com.example.espl.val_vs_var_in_kotlin E/val c: :: 3
//04-24 12:27:08.054 1661-1661/com.example.espl.val_vs_var_in_kotlin E/Value of city of person: - City:: Ahmedabad
//04-24 12:27:08.054 1661-1661/com.example.espl.val_vs_var_in_kotlin E/log of val person: after change of address name,street :: Person(name=Ram, age=50, address=Address(name=Maharshi, street=Dalal street, city=Ahmedabad))
//04-24 12:27:08.054 1661-1661/com.example.espl.val_vs_var_in_kotlin E/log of val person: after change of var address :: Person(name=Tarun, age=50, address=Address(name=Raj street name, street=Raj street, city=Rajkot))
}

Alarm Manager Example Android Kotlin

MainActivity.kt
package com.example.espl.alarmmanagerexamplekotlin

import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.view.View
import kotlinx.android.synthetic.main.activity_main.*

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
     
        val alarmReceiver=AlarmReceiver()

        btnSetAlarm.setOnClickListener(View.OnClickListener { v: View? ->
            //This will set repeating alarm on start of the app
           //On button click alarmManager will set exact repeating alarm android at interval of 1minute
            alarmReceiver.setRepeatingAlarmReminder(this)
        })

        btnCancelAlarm.setOnClickListener(View.OnClickListener { v: View? ->
            // this cancel repeating alarm on start of the app
            alarmReceiver.cancelAlarm(this)
        })
    }
}
BootBroadcastReceiver.kt
package com.example.espl.alarmmanagerexamplekotlin

import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent

class  BootBroadcastReceiver : BroadcastReceiver() {
    override fun onReceive(context: Context?, intent: Intent?) {
        val alarmReceiver = AlarmReceiver()
        if(intent?.action.equals(Intent.ACTION_BOOT_COMPLETED)){
            alarmReceiver.setRepeatingAlarmReminder(context!!);
            }
    }
}
AlarmSchedulingService.kt
package com.example.espl.alarmmanagerexamplekotlin

import android.content.Context
import android.content.Intent
import android.support.v4.app.JobIntentService
import android.util.Log
/**
 * JobIntentClass written in Kotlin
 **/
class AlarmSchedulingService : JobIntentService() {
    //Constant ID to recognise the job
    val JOB_ID = 1000
    fun enqueueWork(context: Context , work:Intent) {
        enqueueWork(context, AlarmSchedulingService::class.java, JOB_ID, work)
    }

    override fun onHandleWork(p0: Intent) {
        //JobIntentService as a android background service will handle the work assigned by alarmmanager intent in this example
        //do your work here.
        Log.e("onHandleWorkCalled","::"+p0.extras.getString("RepeatingAlarm"))
    }
}

AlarmReceiver.kt
package com.example.espl.alarmmanagerexamplekotlin

import android.app.AlarmManager
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.app.PendingIntent
import java.util.Date
import java.text.SimpleDateFormat


class AlarmReceiver: BroadcastReceiver(){
    override fun onReceive(context: Context?, intent: Intent?) {

        val service = Intent(context, AlarmSchedulingService::class.java)
//        Log.e("onHandleWorkCalled","::onReceive"+ intent?.extras?.getString("RepeatingAlarm"))
//        service.putExtra("RepeatingAlarm", intent?.extras?.getString("RepeatingAlarm"));
        val dateFormat = SimpleDateFormat("yyyy-MM-dd hh:mm:ss a")
        service.putExtra("RepeatingAlarm","Time:"+dateFormat.format(Date()))
        AlarmSchedulingService().enqueueWork(context!!,service)
    }

    fun setRepeatingAlarmReminder(context:Context) {
//Below code is to set alarm in android programmatically with repeating interval of 1 minute
        val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
        val intent = Intent(context, AlarmReceiver::class.java)
        val pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0)
        alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), (1000 * 60).toLong(), pendingIntent) // Millisec * Second
    }

    fun cancelAlarm(context: Context) {
        val intent = Intent(context, AlarmReceiver::class.java)
        val sender = PendingIntent.getBroadcast(context, 0, intent, 0)
        val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
        alarmManager.cancel(sender)
    }
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="com.example.espl.alarmmanagerexamplekotlin">

    <uses-permission android:name="android.permission.WAKE_LOCK"></uses-permission>
 
    <application
            android:allowBackup="true"
            android:icon="@mipmap/ic_launcher"
            android:label="@string/app_name"
            android:roundIcon="@mipmap/ic_launcher_round"
            android:supportsRtl="true"
            android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>

                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>

        <receiver android:process=":remote" android:name=".AlarmReceiver"></receiver>

        <receiver android:name=".BootBroadcastReceiver">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED"></action>
            </intent-filter>
        </receiver>

        <service
                android:name=".AlarmSchedulingService"
                android:permission="android.permission.BIND_JOB_SERVICE" />
    </application>

</manifest>

activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:orientation="vertical"
        android:layout_height="match_parent"
        android:gravity="center_horizontal"
        tools:context=".MainActivity">

    <Button
            android:id="@+id/btnSetAlarm"
            android:layout_margin="20dp"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Start Alarm-set Repeating Alarm Reminder"
            android:textAllCaps="false"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent"/>

    <Button
            android:id="@+id/btnCancelAlarm"
            android:layout_margin="20dp"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Cancel Alarm - cancel the repeating Alarm"
            android:textAllCaps="false"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent"/>

</LinearLayout>
Output log of repeating alarm android kotlin:
04-23 18:18:18.219 10840-12057/com.example.espl.alarmmanagerexamplekotlin E/onHandleWorkCalled: ::Time:2019-04-23 06:18:18 PM

04-23 18:19:46.961 10840-12198/com.example.espl.alarmmanagerexamplekotlin E/onHandleWorkCalled: ::Time:2019-04-23 06:19:46 PM

04-23 18:20:46.735 10840-12297/com.example.espl.alarmmanagerexamplekotlin E/onHandleWorkCalled: ::Time:2019-04-23 06:20:46 PM

04-23 18:21:46.788 10840-12341/com.example.espl.alarmmanagerexamplekotlin E/onHandleWorkCalled: ::Time:2019-04-23 06:21:46 PM

04-23 18:22:48.589 10840-13166/com.example.espl.alarmmanagerexamplekotlin E/onHandleWorkCalled: ::Time:2019-04-23 06:22:48 PM

04-23 18:23:48.848 10840-13372/com.example.espl.alarmmanagerexamplekotlin E/onHandleWorkCalled: ::Time:2019-04-23 06:23:48 PM

RealmException - 'Paper' has a primary key, use 'createObject(Class, Object)' instead

    --------- beginning of crash
04-20 11:59:46.918 7408-7408/quizcounter.geeks.compete.myapplication E/AndroidRuntime: FATAL EXCEPTION: main
    Process: quizcounter.geeks.compete.myapplication, PID: 7408
    io.realm.exceptions.RealmException: 'Paper' has a primary key, use 'createObject(Class<E>, Object)' instead.
        at io.realm.Realm.createObjectInternal(Realm.java:998)
        at io.realm.Realm.createObject(Realm.java:977)
        at quizcounter.geeks.compete.myapplication.SplashScreenActivity$setAllPaperDataToDB$1.onDataChange(SplashScreenActivity.java:531)
        at com.google.firebase.database.Query$1.onDataChange(com.google.firebase:firebase-database@@16.1.0:183)
        at com.google.firebase.database.core.ValueEventRegistration.fireEvent(com.google.firebase:firebase-database@@16.1.0:75)
        at com.google.firebase.database.core.view.DataEvent.fire(com.google.firebase:firebase-database@@16.1.0:63)
        at com.google.firebase.database.core.view.EventRaiser$1.run(com.google.firebase:firebase-database@@16.1.0:55)
        at android.os.Handler.handleCallback(Handler.java:742)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:157)
        at android.app.ActivityThread.main(ActivityThread.java:5603)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:774)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:652)

Only valid managed objects can be copied from Realm - Android

04-20 11:40:01.766 464-464/quizcounter.geeks.compete.myapplication E/AndroidRuntime: FATAL EXCEPTION: main
    Process: quizcounter.geeks.compete.myapplication, PID: 464
java.lang.IllegalArgumentException: Only valid managed objects can be copied from Realm.
        at io.realm.Realm.checkValidObjectForDetach(Realm.java:1745)
        at io.realm.Realm.copyFromRealm(Realm.java:1418)
        at io.realm.Realm.copyFromRealm(Realm.java:1391)
        at quizcounter.geeks.compete.myapplication.SplashScreenActivity$setAllPaperDataToDB$1.onDataChange(SplashScreenActivity.java:546)
        at com.google.firebase.database.Query$1.onDataChange(com.google.firebase:firebase-database@@16.1.0:183)
        at com.google.firebase.database.core.ValueEventRegistration.fireEvent(com.google.firebase:firebase-database@@16.1.0:75)
        at com.google.firebase.database.core.view.DataEvent.fire(com.google.firebase:firebase-database@@16.1.0:63)
        at com.google.firebase.database.core.view.EventRaiser$1.run(com.google.firebase:firebase-database@@16.1.0:55)
        at android.os.Handler.handleCallback(Handler.java:742)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:157)
        at android.app.ActivityThread.main(ActivityThread.java:5603)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:774)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:652)

Realm access from incorrect thread. Realm objects can only be accessed on the thread they were created

04-18 10:56:13.329 9961-10237/quizcounter.geeks.compete.myapplication E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #6
    Process: quizcounter.geeks.compete.myapplication, PID: 9961
    java.lang.RuntimeException: An error occurred while executing doInBackground()
        at android.os.AsyncTask$3.done(AsyncTask.java:309)
        at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:354)
        at java.util.concurrent.FutureTask.setException(FutureTask.java:223)
        at java.util.concurrent.FutureTask.run(FutureTask.java:242)
        at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
        at java.lang.Thread.run(Thread.java:818)
     Caused by: java.lang.IllegalStateException: Realm access from incorrect thread. Realm objects can only be accessed on the thread they were created.
        at io.realm.BaseRealm.checkIfValid(BaseRealm.java:442)
        at io.realm.quizcounter_geeks_compete_myapplication_RealmUtils_PaperRealmProxy.realmGet$paperData(quizcounter_geeks_compete_myapplication_RealmUtils_PaperRealmProxy.java:120)
        at quizcounter.geeks.compete.myapplication.SplashScreenActivity$setQuestionsWithJsoup.doInBackground(SplashScreenActivity.java:562)
        at quizcounter.geeks.compete.myapplication.SplashScreenActivity$setQuestionsWithJsoup.doInBackground(SplashScreenActivity.java:556)
        at android.os.AsyncTask$2.call(AsyncTask.java:295)
        at java.util.concurrent.FutureTask.run(FutureTask.java:237)
        at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
        at java.lang.Thread.run(Thread.java:818)

Async query cannot be created on current thread. Realm cannot be automatically updated on a thread without a looper

    --------- beginning of crash
04-17 17:31:36.081 32449-32733/quizcounter.geeks.compete.myapplication E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #2
    Process: quizcounter.geeks.compete.myapplication, PID: 32449
    java.lang.RuntimeException: An error occurred while executing doInBackground()
        at android.os.AsyncTask$3.done(AsyncTask.java:309)
        at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:354)
        at java.util.concurrent.FutureTask.setException(FutureTask.java:223)
        at java.util.concurrent.FutureTask.run(FutureTask.java:242)
        at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
        at java.lang.Thread.run(Thread.java:818)
     Caused by: java.lang.IllegalStateException: Async query cannot be created on current thread. Realm cannot be automatically updated on a thread without a looper.
        at io.realm.internal.android.AndroidCapabilities.checkCanDeliverNotification(AndroidCapabilities.java:54)
        at io.realm.RealmQuery.findAllAsync(RealmQuery.java:1811)
        at quizcounter.geeks.compete.myapplication.SplashScreenActivity$checkNotifIDsData.doInBackground(SplashScreenActivity.java:302)
        at quizcounter.geeks.compete.myapplication.SplashScreenActivity$checkNotifIDsData.doInBackground(SplashScreenActivity.java:280)
        at android.os.AsyncTask$2.call(AsyncTask.java:295)
        at java.util.concurrent.FutureTask.run(FutureTask.java:237)
        at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
        at java.lang.Thread.run(Thread.java:818)
 
 
    --------- beginning of system

How to programmatically set drawableLeft on Android button in Kotlin?

MainActivity.kt
package com.example.espl.drawableleftkotlinbutton
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.view.View
import kotlinx.android.synthetic.main.activity_main.*

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        /**
         * Sets the Drawables (if any) to appear to the left of, above, to the
         * right of, and below the text. Use 0 if you do not want a Drawable there.
         * The Drawables' bounds will be set to their intrinsic bounds.
         * <p>
         * Calling this method will overwrite any Drawables previously set using
         * {@link #setCompoundDrawablesRelative} or related methods.
         *
         * @param left Resource identifier of the left Drawable.
         * @param top Resource identifier of the top Drawable.
         * @param right Resource identifier of the right Drawable.
         * @param bottom Resource identifier of the bottom Drawable.
         */

        button1.setOnClickListener(View.OnClickListener {

            //Programmatically set drawableLeft on Android button - setting the smiley PNG image
            button2.setCompoundDrawablesWithIntrinsicBounds(R.drawable.smiley, 0, 0, 0);
//            or
//            val drawable = ContextCompat.getDrawable(this, R.drawable.smiley)
//            button2.setCompoundDrawablesWithIntrinsicBounds(drawable, null, null, null)

            //Programmatically set drawableLeft on Android button - setting the andriod VectorDraawable
                        button3.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_android_black_24dp, 0, 0, 0);
//            or
            //            val vectorDrawable = ContextCompat.getDrawable(this, R.drawable.ic_android_black_24dp)
//            button3.setCompoundDrawablesWithIntrinsicBounds(vectorDrawable, null, null, null)
        })

    }
}

activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:padding="20dp"
        android:layout_height="match_parent"
        tools:context=".MainActivity">

    <Button
            android:layout_gravity="center"
            android:id="@+id/button1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Click to programmatically set drawableLeft on below buttons"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent"/>

    <Button
            android:layout_centerInParent="true"
            android:layout_below="@id/button1"
            android:id="@+id/button2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="BUTTON 2 -set png image"
            android:drawablePadding="5dp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent"/>

    <Button
            android:layout_centerInParent="true"
            android:layout_below="@id/button2"
            android:id="@+id/button3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="BUTTON 3 -set VectorDrawable"
            android:drawablePadding="5dp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent"/>

</RelativeLayout>

Testing devices:
//Tested on below devices working fine on both devices (tested for above kotlin code)
// HTC Desire 620G - Android OS - Android Version - 4.4.2 - KitKat API 19
// RedMi note 3 - Android OS - Android Version - 6.0.1 - Android – Marshmallow - API level 23
It's working on Kitkat device When you are using an android vector drawable, So the above Kotlin code has backward compatibility for API below 21

How to Convert Map (HashMap) to List in Kotlin Android

This example Program to Convert Map (HashMap) to List in Kotlin Android

MainActivity.kt
package com.example.espl.hashmaptolistkotlin
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import java.security.KeyPair

class MainActivity : AppCompatActivity() {
    //    fun <K, V> hashMapOf(): HashMap<K, V>
    //    Returns an empty new HashMap.
    //Method hashMapOf() in Kotlin
    val hashMap: HashMap<Int,String> = hashMapOf()

override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

    hashMap.put(1,"Value1")
    hashMap.put(2,"Value2")
    hashMap.put(3,"Value3")
    hashMap.put(4,"Value4")
    hashMap.put(5,"Value5")
        //print hash map in Log
        Log.e("hashmap","::"+hashMap)

    //         Returns a [List] containing all key-value pairs.
    //        public fun <K, V> Map<out K, V>.toList(): List<Pair<K, V>>
        // Convert Kotlin Map to List using toList() method
        val pairKeyValueList : List<Pair<Int, String>> = hashMap.toList();
        Log.e("HashmapPairKeyValueList","::"+pairKeyValueList)

        // Convert Kotlin Map to List of keys after extracting the keys
        //public Set<K> keySet() method return a set view of the keys contained in this map
        val listKeys : Set<Int> = hashMap.keys
        //Convert the returned set to ArrayList
        val arraListOfKeys: List<Int> = ArrayList<Int>(listKeys.toList())
        Log.e("hashmap:arraListOfKeys","::"+arraListOfKeys)

        // Convert Kotlin Map to List after extracting the values
        //public Collection<V> values() method return a view of the values contained in this map
        val listValues = hashMap.values
        //Convert the returned Collection to ArrayList
        val arraListOfvalues: List<String> = ArrayList<String>(listValues.toList())
        Log.e("hashmap:arraListOfvalues","::"+arraListOfvalues)

        val students:HashMap<Int,Student> = hashMapOf()
        students.put(1, Student("Ram", "VI", Address("New street", "Ahmedabad")))
        students.put(2, Student("Raju", "V", Address("Green cross", "Rajkot")))

        val pairKeyValueListStudents:ArrayList<Pair<Int,Student>>  = ArrayList(students.toList())
        Log.e("HashmapPairKeyValueList","::"+pairKeyValueListStudents)

        val listKeysStudents: Set<Int> = students.keys
        Log.e("map:listKeysStudents","::"+listKeysStudents)

        //public Collection<V> values() method return a view of the values(student objects) contained in this map
        val listValuesStudents:ArrayList<Student> = ArrayList(students.values)
        Log.e("listValuesStudents","::"+listValuesStudents)

        val listValuesStudentsAddress:ArrayList<Address> = ArrayList(students.values.map { x->x.address})
        Log.e("listValStudentsAddress","::"+listValuesStudentsAddress)

// While working with Map Object, we can associate with map(transform: (T) -> R) function to customise a returned-list
        val listValuesStudentsCity: List<String?> = students.values.map { x->x.address.city}
        Log.e("listValuesStudentsCity","::"+listValuesStudentsCity)
    }

    data class Address(
        var street : String? = null,
        var city : String? = null
    ){}

    data class Student(
        var name: String? = null,
        var std: String? = null,
        var address: Address = Address()) {
    }
}
Output:
com.example.espl.hashmaptolistkotlin E/hashmap: ::{4=Value4, 1=Value1, 5=Value5, 3=Value3, 2=Value2}
com.example.espl.hashmaptolistkotlin E/HashmapPairKeyValueList: ::[(4, Value4), (1, Value1), (5, Value5), (3, Value3), (2, Value2)]
com.example.espl.hashmaptolistkotlin E/hashmap:arraListOfKeys: ::[4, 1, 5, 3, 2]
com.example.espl.hashmaptolistkotlin E/hashmap:arraListOfvalues: ::[Value4, Value1, Value5, Value3, Value2]
com.example.espl.hashmaptolistkotlin E/HashmapPairKeyValueList: ::[(1, Student(name=Ram, std=VI, address=Address(street=New street, city=Ahmedabad))), (2, Student(name=Raju, std=V, address=Address(street=Green cross, city=Rajkot)))]

com.example.espl.hashmaptolistkotlin E/map:listKeysStudents: ::[1, 2]
com.example.espl.hashmaptolistkotlin E/listValuesStudents: ::[Student(name=Ram, std=VI, address=Address(street=New street, city=Ahmedabad)), Student(name=Raju, std=V, address=Address(street=Green cross, city=Rajkot))]

com.example.espl.hashmaptolistkotlin E/listValStudentsAddress: ::[Address(street=New street, city=Ahmedabad), Address(street=Green cross, city=Rajkot)]
com.example.espl.hashmaptolistkotlin E/listValuesStudentsCity: ::[Ahmedabad, Rajkot]

android kotlin hashmap initialization

MainActivity.kt
package com.example.espl.hashmapkotlinapp
import android.os.Build
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.util.Log

class MainActivity : AppCompatActivity() {
        // Different ways for hashmap initialization in Kotlin Android
        //    fun <K, V> hashMapOf(): HashMap<K, V>
        //    Returns an empty new HashMap.
        //    Method hashMapOf() in Kotlin
        val hashMap: HashMap<Int,String> = hashMapOf()

        //    Returns a new HashMap with the specified contents, given as a list of pairs where the  first component is the key and the second is the value.
        //    fun <K, V> hashMapOf(vararg pairs: Pair<K, V>): HashMap<K, V>
        // kotlin init hashmap with values
     val specifiedContentsMap: HashMap<Int, String> = hashMapOf(1 to "x", 2 to "y", -1 to "zz")

        //define empty hash map
        val initEmptyHashMap:HashMap<Int,String> = HashMap()

        //    initialize with its initial capacity of 3
        val initialCapacityHashMap:HashMap<Int,String> = HashMap(3)

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // kotlin hashmap put example - add item
        hashMap.put(1,"Value1")
        hashMap.put(2,"Value2")
        hashMap.put(3,"Value3")
        hashMap.put(4,"Value4")
        hashMap.put(5,"Value5")

        // kotlin hashmap add item
        initEmptyHashMap.put(1,"Value1")
        initEmptyHashMap.put(2,"Value2")
        initEmptyHashMap.put(3,"Value3")

        initialCapacityHashMap.put(1,"Value1")
        initialCapacityHashMap.put(2,"Value2")
        initialCapacityHashMap.put(3,"Value3")
        initialCapacityHashMap.put(4,"Value4")

        //print hash map in Log
        Log.e("hashmap","::"+hashMap)
        Log.e("specifiedContentsMap","::"+specifiedContentsMap)
        Log.e("initEmptyHashMap","::"+initEmptyHashMap)
        Log.e("initialCapacityHashMap","::"+initialCapacityHashMap)
    }
}

Output:
com.example.espl.hashmapkotlinapp E/hashmap: ::{4=Value4, 1=Value1, 5=Value5, 3=Value3, 2=Value2}
com.example.espl.hashmapkotlinapp E/specifiedContentsMap: ::{-1=zz, 1=x, 2=y}
com.example.espl.hashmapkotlinapp E/initEmptyHashMap: ::{1=Value1, 3=Value3, 2=Value2}
com.example.espl.hashmapkotlinapp E/initialCapacityHashMap: ::{4=Value4, 1=Value1, 3=Value3, 2=Value2}

How to parse JSON in Kotlin Android?

This kotlin json parser example using gson discusses following points:
1)  Convert a data class in Kotlin to JSON string using Gson Java library
2)  How to parse JSON String to a Data Model Class / Kotlin bean

MainActivity.kt
package com.example.espl.parsejsoninkotlin

import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import com.google.gson.Gson

class MainActivity : AppCompatActivity() {
//The TestModelClass with 3 attributes: id name and city. So, the JSON string would be as below
    val JSON_STRING: String ="{\"id\":1,\"name\":ram,\"city\":\"AMD\"}"

    // initialise gson var
    var gson = Gson()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

    //Convert from JSON String to a Data Model Class object
        var testModel = gson.fromJson(JSON_STRING, TestModelClass::class.java)
        Log.e("testModel:City","::"+testModel.city)

        //Convert to JSON String from Data Model Class
        val jsonString = gson.toJson(TestModelClass(1,"Navu","KLKT"))
        Log.e("jsonString:","fromModelClass::"+jsonString)
    }

// Create a data class TestModelClass which Convert json string data to Kotlin Bean
// Also, use to convert a data class in Kotlin to JSON string
  data class TestModelClass(
        val id: Int,
        val name: String,
        val city: String
    )
}

build.gradle (Module:app)
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'

android {
    compileSdkVersion 28
    defaultConfig {
        applicationId "com.example.espl.parsejsoninkotlin"
        minSdkVersion 15
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation"org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
    implementation 'com.android.support:appcompat-v7:28.0.0'
    implementation 'com.android.support.constraint:constraint-layout:1.1.3'

    implementation 'com.google.code.gson:gson:2.8.5'

    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}

Kotlin Android - Static method in Kotlin - Companion object example

This example contains example with follwowing points:
1) Create static method in kotlin - kotlin companion object
2) How to use companion class to call method from within Java code
3) How to use companion class to call method from within Kotlin code
4) @JvmStatic - You can either add a @JvmStatic annotation or name your companion class to call method from within Java code
5) Pass MainActivity context to static method and use it to toast message in static function of kotlin companion object.

MainActivity.kt
package com.example.espl.staticmethodkotlin

import android.content.Context
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.widget.Toast

class MainActivity : AppCompatActivity() {
//Equivalent of Java static methods in Kotlin is kotlin Companion object
/**
 The java code for the static function is like this:
      public static int foo(Context context) {
            Toast.makeText(context, "Called foo", Toast.LENGTH_SHORT).show();
      }
 **/

//    create static method in kotlin
//kotlin companion object
companion object {
        @JvmStatic
        fun foo(context: Context,string: String) {
//            toast("Hello World!");
            Toast.makeText(context, "Called foo from: "+string, Toast.LENGTH_SHORT).show();
        }

    fun bar(context: Context,string: String) {
        Toast.makeText(context, "Called bar from: "+string, Toast.LENGTH_SHORT).show();
        }
}

override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // Use foo() method from inside Kotlin code
        MainActivity.foo(this,"MainActivity");

       //use it from inside Kotlin code
        MainActivity.bar(this,"MainActivity");

        val testobject: TestJavaClass= TestJavaClass(this)
        testobject.callMehodInJavaClass()
    }
}

TestJavaClass.java
package com.example.espl.staticmethodkotlin;
import android.content.Context;

public class TestJavaClass {
    Context mContext;
    public TestJavaClass(Context context) {
        mContext=context;
    }

void callMehodInJavaClass(){
//    You can either add a @JvmStatic annotation or name your companion class to call method from within Java code

   MainActivity.Companion.bar(mContext,"TestJavaClass-callMehodInJavaClass"); //works
//    If you don't like having to specify the Companion like above, then need to add a @JvmStatic            annotation in method decleration

   MainActivity.foo(mContext,"TestJavaClass-callMehodInJavaClass");  //  @JvmStatic

//    MainActivity.bar(mContext);
//    This function not work as  @JvmStatic is not added in the method/function bar() decleration

//    MainActivity.Companion.foo(mContext,"TestJavaClass-callMehodInJavaClass");
//     Above method works if  @JvmStatic is not added before the method/function foo() decleration, need to specify the Companion as above
    }
}


retrieving data from firebase kotlin

package com.example.espl.myapplication22

import android.os.Bundle
import android.support.design.widget.Snackbar
import android.support.design.widget.NavigationView
import android.support.v4.view.GravityCompat
import android.support.v4.view.ViewPager
import android.support.v7.app.ActionBarDrawerToggle
import android.support.v7.app.AppCompatActivity
import android.view.Menu
import android.view.MenuItem
import com.google.firebase.database.*
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.app_bar_main.*


class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelectedListener {

    lateinit var mDatabaseReference : DatabaseReference

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        setSupportActionBar(toolbar)

        mDatabaseReference = FirebaseDatabase.getInstance().getReference();

        databasereference.child("desc").addValueEventListener(object : ValueEventListener{
            override fun onDataChange(snapshot: DataSnapshot) {
            println("TestBed: ${snapshot.value}")
        }

                override fun onCancelled(error: DatabaseError) {}
    })


    }

 
}

java.lang.RuntimeException: Unable to instantiate activity ComponentInfo Kotlin Android


I found these in Warning in Manifest.xml::

".MainActivity" in <activity android:name=".MainActivity"> is not a concrete class.

In android Studio error log is as below:
java.lang.RuntimeException: Unable to instantiate activity ComponentInfo Kotlin Android
   Process: com.example.espl.myapplication22, PID: 9829
    java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.example.espl.myapplication22/com.example.espl.myapplication22.MainActivity}: java.lang.InstantiationException: java.lang.Class<com.example.espl.myapplication22.MainActivity> cannot be instantiated
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2398)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2547)
        at android.app.ActivityThread.access$1100(ActivityThread.java:151)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1398)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:157)
        at android.app.ActivityThread.main(ActivityThread.java:5603)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:774)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:652)
     Caused by: java.lang.InstantiationException: java.lang.Class<com.example.espl.myapplication22.MainActivity> cannot be instantiated
        at java.lang.Class.newInstance(Native Method)
        at android.app.Instrumentation.newActivity(Instrumentation.java:1068)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2388)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2547)
        at android.app.ActivityThread.access$1100(ActivityThread.java:151)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1398)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:157)
        at android.app.ActivityThread.main(ActivityThread.java:5603)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:774)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:652)

SOLUTION:
Remove the abstract before the class decleration of MainActivity

The library com.google.android.gms:play-services-basement is being requested by various other libraries at [[15.0.1,15.0.1]], but resolves to 16.0.1

The library com.google.android.gms:play-services-basement is being requested by various other libraries at [[15.0.1,15.0.1]], but resolves to 16.0.1. Disable the plugin and check your dependencies tree using ./gradlew :app:dependencies.

I faced this error while added the below line to app gradle:
implementation 'com.google.firebase:firebase-database:16.1.0'

app build gradle after adding above dependency:
apply plugin: 'com.android.application'

android {
    compileSdkVersion 28
    defaultConfig {
        applicationId "quizcounter.geeks.compete.myapplication"
        minSdkVersion 17
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:appcompat-v7:28.0.0'

    implementation 'org.jsoup:jsoup:1.11.3'
    implementation 'com.android.volley:volley:1.1.1'

    implementation 'com.google.firebase:firebase-core:16.0.0'
    implementation 'com.google.firebase:firebase-database:16.1.0'

    implementation 'com.android.support.constraint:constraint-layout:1.1.3'
    implementation 'com.android.support:support-v4:28.0.0'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}

apply plugin: 'com.google.gms.google-services'


updated the firebase-core gradle to below and buid gradle is working fine:

implementation 'com.google.firebase:firebase-core:16.0.4'


Popular Posts