简体   繁体   中英

android - kotlin, custom view, binding, inflating - JNI ERROR (app bug): local reference table overflow (max=512)

I am using kotlin. I am trying create Custom View inside Custom View. I hope, I did it.

Now I would like to change text in my views. I tried use binding. But when is called: SampleMyViewBBinding.inflate(inflater) application shows me error:

JNI ERROR (app bug): local reference table overflow (max=512)

I think application trying call inflating again, again, again, .... Can you help me, what is wrong? How to use binding in Custom View? Thank you.

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
    }
}
class MyViewA : ConstraintLayout {

    constructor(context: Context) : super(context) { init(null, 0) }

    constructor(context: Context, attrs: AttributeSet) : super(context, attrs) { init(attrs, 0) }

    constructor(context: Context, attrs: AttributeSet, defStyle: Int) : super(context, attrs, defStyle) {  init(attrs, defStyle) }

    private fun init(attrs: AttributeSet?, defStyle: Int) {

    }
}
class MyViewB : ConstraintLayout {

    constructor(context: Context) : super(context) { init(null, 0) }

    constructor(context: Context, attrs: AttributeSet) : super(context, attrs) { init(attrs, 0) }

    constructor(context: Context, attrs: AttributeSet, defStyle: Int) : super(context, attrs, defStyle) { init(attrs, defStyle) }

    private fun init(attrs: AttributeSet?, defStyle: Int) {
        Log.i("AW", "init test...1")
        var inflater = LayoutInflater.from(context)
        Log.i("AW", "init test...2")
        var binding = SampleMyViewBBinding.inflate(inflater)
        Log.i("AW", "init test...3")
    }
}

activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/text_Main"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="text_my_view_MAIN" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/text_Main">
        <include layout="@layout/sample_my_view_a" />
    </LinearLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

sample_my_view_a.xml:

<com.myapp.mytestingapplication.MyViewA
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/id_MyViewA">

    <TextView
        android:id="@+id/text_MyViewA"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="text_my_view_A" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/text_MyViewA">
        <include layout="@layout/sample_my_view_b" />
    </LinearLayout>
</com.myapp.mytestingapplication.MyViewA>

sample_my_view_b.xml:

<com.myapp.mytestingapplication.MyViewB
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/text_MyViewB"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="text_my_view_B" />

</com.myapp.mytestingapplication.MyViewB>

I think you messed with the constructors and the init block a bit. You can use JvmOverloads to "automatically" generate the constructors for you. Also, the init block as written below is invoked regardless the constructor being used:

class MyViewA @JvmOverloads constructor(
    context: Context, 
    attrs: AttributeSet? = null, 
    defStyle: Int = 0
) : ConstraintLayout(context, attrs, defStyle) {

    init {
        // 
    }
}

class MyViewB @JvmOverloads constructor(
    context: Context, 
    attrs: AttributeSet? = null, 
    defStyle: Int = 0
) : ConstraintLayout(context, attrs, defStyle) {

    init {
        Log.i("AW", "init test...1")
        var inflater = LayoutInflater.from(context)
        Log.i("AW", "init test...2")
        var binding = SampleMyViewBBinding.inflate(inflater)
        Log.i("AW", "init test...3")
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM