Chinmay Aggarwal
Chinmay Aggarwal

Reputation: 15

It's Saying Variable not Initialised even when it's initialised

I am facing an error related to variable initialization. I got this error in the run logs when I tried to run my application. I am not able to understand what has possibly gone wrong, because I have initialised the variable in MainActivity and also lateinit it in MainActivity. I am new to Stackoverflow and Kotlin both. Please help me out:

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.chinmay.distanceandtime, PID: 20591
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.chinmay.distanceandtime/com.chinmay.distanceandtime.MainActivity}: kotlin.UninitializedPropertyAccessException: lateinit property currentLocation has not been initialized
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3448)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3595)
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2147)
        at android.os.Handler.dispatchMessage(Handler.java:107)
        at android.os.Looper.loop(Looper.java:237)
        at android.app.ActivityThread.main(ActivityThread.java:7807)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1047)
     Caused by: kotlin.UninitializedPropertyAccessException: lateinit property currentLocation has not been initialized
        at com.chinmay.distanceandtime.MainActivity.onCreate(MainActivity.kt:53)
        at android.app.Activity.performCreate(Activity.java:7955)
        at android.app.Activity.performCreate(Activity.java:7944)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1307)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3423)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3595) 
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83) 
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135) 
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2147) 
        at android.os.Handler.dispatchMessage(Handler.java:107) 
        at android.os.Looper.loop(Looper.java:237) 
        at android.app.ActivityThread.main(ActivityThread.java:7807) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1047) 

My MainActivity.kt looks like:

import android.Manifest
import android.content.pm.PackageManager
import android.location.Location
import android.os.Bundle
import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import com.google.android.gms.location.FusedLocationProviderClient
import com.google.android.gms.location.LocationServices
import com.google.android.gms.maps.model.LatLng
import java.util.*

class MainActivity : AppCompatActivity() {
    private lateinit var fusedLocationProviderClient: FusedLocationProviderClient
//    private var destination = Location(18.485934925135574, 73.95844623035339)
    private val permissionCode = 101
    lateinit var currentLocation: Location

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        fusedLocationProviderClient =  LocationServices.getFusedLocationProviderClient(this@MainActivity)

        if (ActivityCompat.checkSelfPermission(
                        this, Manifest.permission.ACCESS_FINE_LOCATION
                ) !=
                PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(
                        this, Manifest.permission.ACCESS_COARSE_LOCATION
                ) !=
                PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(
                    this,
                    arrayOf(Manifest.permission.ACCESS_FINE_LOCATION), permissionCode
            )
            return
        }

        val task = fusedLocationProviderClient.lastLocation
        task.addOnSuccessListener { location ->
            if (location != null) {
                currentLocation = location
                Toast.makeText(applicationContext, currentLocation.latitude.toString() + ", " +
                        currentLocation.longitude, Toast.LENGTH_LONG).show()
            }
        }

        val destination = Location("locationB")
        destination.latitude = 18.485934925135574
        destination.longitude = 73.95844623035339
        val distance = currentLocation.distanceTo(destination).toDouble()

        val Destination_textview = findViewById<TextView>(R.id.Destination_textview)
        Destination_textview.setText("Distance between two Geographic Locations: $distance KMS")
    }
}

My build.gradle looks like this:

plugins {
    id 'com.android.application'
    id 'kotlin-android'
}

android {
    compileSdkVersion 30
    buildToolsVersion "30.0.3"

    defaultConfig {
        applicationId "com.chinmay.distanceandtime"
        minSdkVersion 16
        targetSdkVersion 30
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"

        multiDexEnabled true
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    kotlinOptions {
        jvmTarget = '1.8'
    }
}

dependencies {

    implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
    implementation 'androidx.core:core-ktx:1.3.2'
    implementation 'androidx.appcompat:appcompat:1.2.0'
    implementation 'com.google.android.material:material:1.2.1'
    implementation 'com.google.android.gms:play-services-maps:17.0.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
    testImplementation 'junit:junit:4.+'
    androidTestImplementation 'androidx.test.ext:junit:1.1.2'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
    implementation 'com.google.android.gms:play-services-maps:17.0.0'
    implementation 'com.google.android.gms:play-services-location:17.0.0'
    implementation 'com.google.android.gms:play-services-maps:17.0.0'
    implementation 'com.google.android.libraries.places:places:1.0.0'

    testImplementation 'junit:junit:4.12'
    testImplementation 'junit:junit:4.12'

    implementation 'androidx.multidex:multidex:2.0.1'
}

Upvotes: 0

Views: 122

Answers (2)

SlothCoding
SlothCoding

Reputation: 1706

The problem with your code is that code will access currentLocation even when location is null. In that way, your currentLocation is not initialized and the app will crash. I am not sure if using lateinit here is the best solution because locations can be null and it is better if you just go with a null value in the first place and later check for a null value.

    val task = fusedLocationProviderClient.lastLocation
    task.addOnSuccessListener { location ->
        if (location != null) { // LOCATION IS NULL
            currentLocation = location // VALUE NEVER ASSIGNED
            Toast.makeText(applicationContext, currentLocation.latitude.toString() + ", " +
                    currentLocation.longitude, Toast.LENGTH_LONG).show()
        }
    }

    val destination = Location("locationB")
    destination.latitude = 18.485934925135574
    destination.longitude = 73.95844623035339
    val distance = currentLocation.distanceTo(destination).toDouble() // CURRENT LOCATION IS NULL

    val Destination_textview = findViewById<TextView>(R.id.Destination_textview)
    Destination_textview.setText("Distance between two Geographic Locations: $distance KMS")
}

Upvotes: 1

Muhammad Awais
Muhammad Awais

Reputation: 548

Access currentLocation variable inside addOnSuccessListener.

You are using it outside addOnSuccessListener.

Add it in addOnSuccessListener and remove it from where it is now written.

val destination = Location("locationB")
destination.latitude = 18.485934925135574
destination.longitude = 73.95844623035339
val distance = currentLocation.distanceTo(destination).toDouble()

val Destination_textview = findViewById<TextView>(R.id.Destination_textview)
Destination_textview.setText("Distance between two Geographic Locations: $distance KMS")

Upvotes: 1

Related Questions