Android上下文NullPointerException:尝试在空对象引用上调用虚方法

时间:2018-05-15 22:06:16

标签: android kotlin android-context

我想在我的片段中创建TableLayout以插入数据。 我在下面使用了这个方法。

我必须在onCreated视图方法之外调用方法 updateTable

但我总是遇到这个错误:

  

java.lang.NullPointerException:尝试调用虚方法' android.content.res.Resources android.content.Context.getResources()'在空对象引用上

错误的完整代码:

E/AndroidRuntime: FATAL EXCEPTION: main
                  Process: com.tharwa.tdm2_exo2, PID: 5480
                  java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.Resources android.content.Context.getResources()' on a null object reference
                      at android.view.ViewConfiguration.get(ViewConfiguration.java:364)

                      ...

                      at com.tharwa.tdm2_exo2.TableAgent.TablePresentation.updateTable(TablePresentation.kt:61)

我尝试了几种方法来避免此错误,但仍然会出现。我试图从onCreatedView获取上下文但不起作用。

这是我的功能:

class TablePresentation : DialogFragment(),tableContract.View
{
    ....

     override fun updateTable(temps: ArrayList<Double>)
     {
         for (i in 0 until temps.size) {
        val row =  TableRow(activity)
        row.setLayoutParams(LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,
                LinearLayout.LayoutParams.WRAP_CONTENT))
        row.setWeightSum(2.0f)
        val tv1 = TextView(activity)
        val tv2= TextView(activity)

        ...

        table!!.addView(row, i)
        }
     }

}

以下是该类的完整代码:

class TablePresentation : DialogFragment(),tableContract.View
{

    var table: TableLayout?=null

    override fun onCreateView(inflater: LayoutInflater?, parent: ViewGroup?, state: Bundle?): View? {
        super.onCreateView(inflater, parent, state)
        val view = activity.layoutInflater.inflate(R.layout.table_fragment, parent, false)
        view.findViewById<View>(R.id.button_close)?.setOnClickListener({ dismiss() })
        return view
    }

    override fun onViewCreated(view: View?, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        table = view?.findViewById<View>(R.id.simpleTableLayout) as TableLayout
    }


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

    override fun onStart() {
      ...
    }


     override fun updateTable(temps: ArrayList<Double>)
     {
        ....
     }

}

以下是我将视图附加到控制器的方法:

class PaletteController
{
    var father: FatherController?=null
    val view: PaletterPresentation
    var model:PaletteAbstraction?=null
    var TableSon:TableController?=null

    constructor(view:PaletterPresentation)
    {
        this.view=view
        view.controller=this
        this.model= PaletteAbstraction()

    }
    ....

    fun notifyTableChild()
    {
        TableSon= TableController(view.getTableChild())
        setChildSFather()
        TableSon?.updateTable( father!!.giveTemps())
    }
}

这就是我创建片段的原因:

class PaletterPresentation: Fragment(), PaletteContract.View
{
    var views: View? = null
    var controller: PaletteController?=null

    val tablePresentation=TablePresentation()

    override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?,
                              savedInstanceState: Bundle?): View? {
        views = inflater!!.inflate(R.layout.palette_fragement, container, false)
        return views
    }
    override fun onViewCreated(view: View?, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        fab.setOnClickListener { view ->
            val ft = childFragmentManager.beginTransaction()
            tablePresentation.show(ft, ContentValues.TAG)
            controller?.notifyTableChild()
        }
    }


    override fun getTableChild(): TablePresentation {
        return tablePresentation
    }

}

我真的不知道如何解决这个问题。

2 个答案:

答案 0 :(得分:0)

您的片段未附加。

你这样做:

    TableSon= TableController(view.getTableChild())
    setChildSFather()
    TableSon?.updateTable( father!!.giveTemps())

getTableChild返回已初始化的内容:

val tablePresentation=TablePresentation()

这会造成一个&#34;流氓&#34;没有附加任何东西的碎片。

解决此特定问题的一种方法是记住TablePresentation片段中的数组,并从updateTable调用onAttach

编辑:记住&#34;记住&#34;我的意思是将它保存到参数中,而不仅仅是存储在成员中。

答案 1 :(得分:0)

@Dennis K我们可以从onAttach甚至从onViewCreated调用该方法。 我知道这很完美。

但我的问题是为什么我们不能这样做**我所说的方法的调用是在这两种方法之外**为什么我们不能这样做?

最后,因为我没有找到答案,为什么我从onViewCreated.or调用我的方法,即使在onAttached.like上你也说过@Dennis K.

这是电话

 override fun onViewCreated(view: View?, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        table = view?.findViewById<View>(R.id.simpleTableLayout) as TableLayout
        updateTable()
    }

这是函数

fun updateTable()
     {
         val temps=controller?.getTemps()
         for (i in 0 until temps!!.size) {
        val row =  TableRow( activity)
        row.setLayoutParams(LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,
                LinearLayout.LayoutParams.WRAP_CONTENT))
        row.setWeightSum(2.0f)
        val tv1 = TextView( activity)
        val tv2= TextView(activity)

        tv1.setLayoutParams(TableRow.LayoutParams(0, ViewGroup.LayoutParams.WRAP_CONTENT, 1.0f))
        tv2.setLayoutParams(TableRow.LayoutParams(0, ViewGroup.LayoutParams.WRAP_CONTENT, 1.0f))

        tv1.setGravity(Gravity.CENTER)
        tv2.setGravity(Gravity.CENTER)

        tv1.setText((i+1).toString())
        tv2.setText(temps.get(i).toString())

        // finally add our textviews to TableRow
        row.addView(tv1)
        row.addView(tv2)
        //finally add our TableRow to Tablelayout
        table!!.addView(row, i)
        }
     }

为什么在onAttach / onViewCreated之外为什么我们无法接收有效的活动(这是一个上下文)。