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

问题描述

我在Android Studio中创建了一个自定义视图模板和一个自该模板继承的自定义视图。如果我在自定义视图中访问方法,则整个应用程序都会崩溃,并在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.824 587-587 /? I / Process:正在发送信号。 PID:587 SIG: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,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,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,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,5 * density)
    constraintSet.connect(txtTitle.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).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" />

在活动中,我在editText字段中输入了一个值:

class Formularactivity : FormularTemplate() {

    override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    //Connection to the XML-Layout-File
    setContentView(R.layout.activity_form_bike)

    ...
    etxt_LGEW.setText("Leergewicht")
    ...
}
}

感谢您的帮助

解决方法

它看起来与类本身没有任何关系,但是与您的Activity代码中的某些内容有关:

open my $fh,'<',$log1 or die "Cannot open '$log1': $!\n";

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