Android 如果我在自定义视图中访问某个方法,应用程序将崩溃

Android 如果我在自定义视图中访问某个方法,应用程序将崩溃,android,kotlin,android-custom-view,Android,Kotlin,Android Custom View,我在AndroidStudio中创建了一个自定义视图模板和一个自定义视图,它们继承自该模板。如果我在自定义视图中访问一个方法,整个应用程序将崩溃,并在Logcat中显示以下错误消息: 2020-11-01 13:53:22.790 587-587/de.rescuemod E/AndroidRuntime: FATAL EXCEPTION: main Process: de.rescuemod, PID: 587 java.lang.RuntimeException: Unable to sta

我在AndroidStudio中创建了一个自定义视图模板和一个自定义视图,它们继承自该模板。如果我在自定义视图中访问一个方法,整个应用程序将崩溃,并在Logcat中显示以下错误消息:

2020-11-01 13:53:22.790 587-587/de.rescuemod E/AndroidRuntime: FATAL EXCEPTION: main
Process: de.rescuemod, PID: 587
java.lang.RuntimeException: Unable to start activity ComponentInfo{de.rescuemod/de.rescuemod.formulars.bike.FormBikeActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void de.rescuemod.customElements.MonoEditText.setText(java.lang.String)' on a null object reference
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2928)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3063)
    at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
    at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
    at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1823)
    at android.os.Handler.dispatchMessage(Handler.java:107)
    at android.os.Looper.loop(Looper.java:198)
    at android.app.ActivityThread.main(ActivityThread.java:6729)
    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:876)
 Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void de.rescuemod.customElements.MonoEditText.setText(java.lang.String)' on a null object reference
    at de.rescuemod.formulars.bike.FormBikeActivity.readDatabase(FormBikeActivity.kt:653)
    at de.rescuemod.formulars.bike.FormBikeActivity.onCreate(FormBikeActivity.kt:598)
    at android.app.Activity.performCreate(Activity.java:7136)
    at android.app.Activity.performCreate(Activity.java:7127)
    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1272)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2908)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3063) 
    at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78) 
    at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108) 
    at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68) 
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1823) 
    at android.os.Handler.dispatchMessage(Handler.java:107) 
    at android.os.Looper.loop(Looper.java:198) 
    at android.app.ActivityThread.main(ActivityThread.java:6729) 
    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:876) 
2020-11-01 13:53:22.824587-587/?I/进程:发送信号。PID:587信号:9

这是我的父级自定义视图模板:

open class CustomElementTemplate(context : Context, attrs : AttributeSet) : ConstraintLayout(context, attrs) {

/* -------------------- Member variables -------------------- */

/** Main linear layout */
val llMain = LinearLayout(context)

/** Title textview */
val txtTitle = TextView(context)

/** Getting the density of the view */
val density = context.displayMetrics.density.toInt()


/* -------------------- Initialization -------------------- */

/**
 * Primary Constructor
 */
init {

    //Constraint layout
    this.id = R.id.cl_customelementtemplate
    setPadding(8 * density, 0, 8 * density, 0)
    background = resources.getDrawable(R.drawable.border_padding, null)
    layoutParams = LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT)



    //Title of the view
    txtTitle.id = R.id.txt_title
    val lpTitle = LayoutParams(
        LayoutParams.WRAP_CONTENT,
        LayoutParams.WRAP_CONTENT
    )

    txtTitle.setBackgroundColor(if (getDarkMode(context)) {
        resources.getColor(R.color.backgroundAccent_dark, null)
    } else {
        resources.getColor(R.color.backgroundAccent_light, null)
    })

    txtTitle.layoutParams = lpTitle
    txtTitle.setPadding(5 * density, 0, 5 * density, 0)
    txtTitle.textSize = 15f
    txtTitle.setTextColor(Color.parseColor("#8A8A8A"))
    txtTitle.visibility = View.GONE
    addView(txtTitle)



    //Main LinearLayout
    llMain.id = R.id.ll_main
    llMain.minimumHeight = 30 * density
    llMain.orientation = LinearLayout.VERTICAL
    llMain.layoutParams = LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT)
    llMain.setPadding(8 * density, 20 * density, 8 * density, 14 * density)
    addView(llMain)
}


/* -------------------- Lifecycle -------------------- */

/**
 * After the layout was completly loaded in the view, execute the code here
 */
override fun onFinishInflate() {
    super.onFinishInflate()

    //Setting margins
    val constraintSet = ConstraintSet()
    constraintSet.clone(this)
    constraintSet.connect(txtTitle.id, ConstraintSet.START, this.id, ConstraintSet.START,5 * density)
    constraintSet.connect(txtTitle.id, ConstraintSet.TOP, this.id, ConstraintSet.TOP,0)
    constraintSet.applyTo(this)
}
}
自定义视图:

class MonoEditText(context: Context, attrs : AttributeSet) : CustomElementTemplate(context, attrs) {

/* -------------------- Member variables -------------------- */

/** EditText element */
private var etxt = EditText(context)



/* -------------------- Initialization -------------------- */

/**
 * Primary Constructor
 */
init {

    //Collect the values from XML
    context.theme.obtainStyledAttributes(attrs, R.styleable.MonoEditText, 0, 0).apply {

        //EditText / AutocompleteText
        if(getBoolean(R.styleable.MonoEditText_autoComplete, false)) {
            etxt = AutoCompleteTextView(context)
        }

        etxt.id = R.id.etxt_main
        etxt.layoutParams = LayoutParams(LayoutParams.MATCH_PARENT, 60 * density)
        llMain.minimumHeight = 30 * density

        llMain.addView(etxt)



        //Fill all kind of textes like titles, subtitles, etc.
        try {
            if(getString(R.styleable.MonoEditText_title)?.isNotEmpty()!!) {
                setTitle(getString(R.styleable.MonoEditText_title)!!)
            }
        } catch ( e: Exception) {}




        //InputType
        when(getString(R.styleable.MonoEditText_inputType)) {
            "0" -> etxt.inputType = InputType.TYPE_NUMBER_FLAG_SIGNED or InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_FLAG_DECIMAL
            "1" -> etxt.inputType = InputType.TYPE_CLASS_NUMBER
            "2" -> etxt.inputType = InputType.TYPE_CLASS_TEXT
            "3" -> etxt.inputType = InputType.TYPE_NUMBER_FLAG_DECIMAL
            "4" -> etxt.inputType = InputType.TYPE_TEXT_FLAG_CAP_WORDS
            "5" -> etxt.inputType = InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS
        }
        
    }
}




/* -------------------- Getter/Setter Methods -------------------- */

/**
 * Set the selected value by string
 * @param   value    String which should be choosen
 */
fun setText(value : String) {
    //etxt.setText(value)
}
}
我在xml活动中添加自定义视图,如下所示:

<de.rescuemod.customElements.MonoEditText
    android:id="@+id/etxt_LGEW"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:inputType="number"
    app:title="@string/LGEW" />

感谢您的帮助

看起来与课程本身无关,但您的活动代码中有一些内容:

Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void de.rescuemod.customElements.MonoEditText.setText(java.lang.String)' on a null object reference
    at de.rescuemod.formulars.bike.FormBikeActivity.readDatabase(FormBikeActivity.kt:653)

查看此堆栈跟踪,问题似乎出在FormBikeActivity中的readDatabase函数中。它表示从该函数调用setText会导致NPE。我们可能需要该函数中的一些代码,以及在onCreate中调用该函数的位置,并使用一些上下文来查看出错的地方。

在最后的代码片段中,
etxt\u LGEW
null
。好的,我能做些什么?对于我想要添加“findviewbyId”并将结果存储在变量中的每个自定义视图?或者有更好的解决方案吗?您可以使用、
findViewById()
或类似的解决方案。这与这是一个自定义视图这一事实无关。在早期版本中,我在自定义视图中使用了一个XML,我用“view.inflate()”将其添加到类中,并且成功了。但我想完全以编程的方式编写,从那时起,它就不再工作了。我需要在每个活动中使用自定义视图50-100次,因此,我需要一种比在每个自定义视图中添加“findviewbyId”更智能的方法。)如果你不按照Commonware的建议使用,你最终总会得到一个NPE。是的,它是说在
FormBikeActivity
的第653行,你在调用
setText
一个
MonoEditText
变量,该变量为空
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void de.rescuemod.customElements.MonoEditText.setText(java.lang.String)' on a null object reference
    at de.rescuemod.formulars.bike.FormBikeActivity.readDatabase(FormBikeActivity.kt:653)