Egis
Egis

Reputation: 5141

Kotlin exception: Parameter specified as non-null is null

I'm getting the exception at line if (text.startsWith(prefix)). How come? What the hell is going on here?

Here's my code.

CustomEditText.kt

import android.content.Context
import android.util.AttributeSet
import android.widget.EditText

class CustomEditText : EditText {

    private val prefix: String = "AS"

    constructor(context: Context) : super(context)

    constructor(context: Context, attrs: AttributeSet) : super(context, attrs)

    constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr)

    constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int, defStyleRes: Int) : super(context, attrs, defStyleAttr, defStyleRes)

    override fun onSelectionChanged(selStart: Int, selEnd: Int) {
        super.onSelectionChanged(selStart, selEnd)
        if (text.startsWith(prefix)) {
            // do something
        }
    }

}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <com.example.myapplication.CustomEditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</LinearLayout>

MainActivity.kt

import android.os.Bundle;

import androidx.appcompat.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity {

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

Stacktrace

2019-11-28 15:58:46.623 11608-11608/com.example.myapplication E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.myapplication, PID: 11608
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.myapplication/com.example.myapplication.MainActivity}: android.view.InflateException: Binary XML file line #7: Binary XML file line #7: Error inflating class com.example.myapplication.CustomEditText
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2821)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2929)
        at android.app.ActivityThread.-wrap11(Unknown Source:0)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1623)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loop(Looper.java:164)
        at android.app.ActivityThread.main(ActivityThread.java:6678)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:830)
     Caused by: android.view.InflateException: Binary XML file line #7: Binary XML file line #7: Error inflating class com.example.myapplication.CustomEditText
     Caused by: android.view.InflateException: Binary XML file line #7: Error inflating class com.example.myapplication.CustomEditText
     Caused by: java.lang.reflect.InvocationTargetException
        at java.lang.reflect.Constructor.newInstance0(Native Method)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:334)
        at android.view.LayoutInflater.createView(LayoutInflater.java:647)
        at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:790)
        at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:730)
        at android.view.LayoutInflater.rInflate(LayoutInflater.java:863)
        at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:824)
        at android.view.LayoutInflater.inflate(LayoutInflater.java:515)
        at android.view.LayoutInflater.inflate(LayoutInflater.java:423)
        at android.view.LayoutInflater.inflate(LayoutInflater.java:374)
        at androidx.appcompat.app.AppCompatDelegateImpl.setContentView(AppCompatDelegateImpl.java:469)
        at androidx.appcompat.app.AppCompatActivity.setContentView(AppCompatActivity.java:140)
        at com.example.myapplication.MainActivity.onCreate(MainActivity.java:12)
        at android.app.Activity.performCreate(Activity.java:7023)
        at android.app.Activity.performCreate(Activity.java:7014)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1215)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2774)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2929)
        at android.app.ActivityThread.-wrap11(Unknown Source:0)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1623)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loop(Looper.java:164)
        at android.app.ActivityThread.main(ActivityThread.java:6678)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:830)
     Caused by: java.lang.IllegalArgumentException: Parameter specified as non-null is null: method kotlin.jvm.internal.Intrinsics.checkParameterIsNotNull, parameter prefix
        at kotlin.text.StringsKt__StringsKt.startsWith(Unknown Source:7)
        at kotlin.text.StringsKt__StringsKt.startsWith$default(Strings.kt:749)
        at com.example.myapplication.CustomEditText.onSelectionChanged(CustomEditText.kt:21)
        at android.widget.TextView.spanChange(TextView.java:9662)
        at android.widget.TextView$ChangeWatcher.onSpanAdded(TextView.java:12121)
        at android.text.SpannableStringBuilder.sendSpanAdded(SpannableStringBuilder.java:1272)
        at android.text.SpannableStringBuilder.setSpan(SpannableStringBuilder.java:773)
        at android.text.SpannableStringBuilder.setSpan(SpannableStringBuilder.java:672)
        at android.text.Selection.setSelection(Selection.java:78)
2019-11-28 15:58:46.624 11608-11608/com.example.myapplication E/AndroidRuntime:     at android.text.Selection.setSelection(Selection.java:87)
        at android.text.method.ArrowKeyMovementMethod.initialize(ArrowKeyMovementMethod.java:312)
        at android.widget.TextView.setText(TextView.java:5532)
        at android.widget.TextView.setText(TextView.java:5400)
        at android.widget.EditText.setText(EditText.java:113)
        at android.widget.TextView.<init>(TextView.java:1652)
        at android.widget.EditText.<init>(EditText.java:88)
        at android.widget.EditText.<init>(EditText.java:84)
        at android.widget.EditText.<init>(EditText.java:80)
        at com.example.myapplication.CustomEditText.<init>(CustomEditText.kt:13)
            ... 26 more

Upvotes: 0

Views: 795

Answers (2)

Alexey Romanov
Alexey Romanov

Reputation: 170899

In JVM (including Android) superclass constructor body runs before subclass field initializers. Since you can see the line

at android.widget.TextView.<init>(TextView.java:1652)

in the stack trace, the problem happens inside TextView's constructor and prefix hasn't been initialized yet.

Since you have the same prefix for any CustomEditText, a simple fix would be to move it into companion object, maybe make it const. Otherwise you could e.g. use by lazy.

Of course, we are inside

at android.widget.EditText.setText(EditText.java:113)

too, so maybe text is still null as well (you'd have to check implementation)...

Upvotes: 2

kaushal malvi
kaushal malvi

Reputation: 72

Use let function with safecall(?.) operator when you are such kind of operation. Using Let keyword, the block will excecute when it get non-null values.

usage:

text?.let {
    // run this code if your 'text' is not null ..
}

Upvotes: 0

Related Questions