简体   繁体   中英

Android context NullPointerException : Attempt to invoke virtual method on a null object reference

I want to create TableLayout in my fragment to insert data. I used for that this methode below.

I have to call the methode updateTable outside of the onCreated view method.

But I got always this error:

java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.Resources android.content.Context.getResources()' on a null object reference

The complete code of the error:

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)

I have tried several ways to avoid this error but still always appear. I tried to get the context from onCreatedView too but does not work.

Here is my function:

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)
        }
     }

}

Here is the complete code of the class:

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>)
     {
        ....
     }

}

and here is how I attach the view to the controller:

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())
    }
}

Here is why I create the fragment:

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
    }

}

I really do not know how to fix this problem.

Your fragment is not attached.

You're doing this:

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

Where getTableChild returns what has been initialized like this:

val tablePresentation=TablePresentation()

This creates an "rogue" Fragment that is not attached to anything.

One way to fix this particular issue would be to remember the array in the TablePresentation fragment and call updateTable from onAttach .

EDIT: By "remember" I mean save it into the arguments, not just store in a member.

@Dennis K weel we can call the method from onAttach or even from onViewCreated. I know that work perfectly.

But my question was why we can not do that **the call of the method i mean ** outside of those 2 methode.Why could not we do that?

Finally because i have not found the answer to my why i have called my methode from onViewCreated.or even on onAttached.like have u said @Dennis K.

Here is the call

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

Here is the function

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)
        }
     }

Why why why outside of onAttach/onViewCreated we can not receive a valid activity (which is a Context).

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