How to fix null pointer for “resp” while observing the value of live data

问题: My code works fine with view model but when I start observing the value using live data in model.d.observe(this, Observer<RespCategories> { r->r...

问题:

My code works fine with view model but when I start observing the value using live data in

model.d.observe(this, Observer<RespCategories> {
                r->resp=r
})

type of r in resp=r is changed from RespCategories to RespCategories? and it does not matches the parameters of pager adapter so i made some changes to it like converting var resp: RespCategories to var resp: RespCategories? = null so a new problem came up while observing the value of r->resp=r resp value is null. How to fix the problem?

kotlin.KotlinNullPointerException   at com.example.xyz.MainActivity.showData(MainActivity.kt:83)
                      at com.example.xyz.MainActivity$fetchData$1.onResponse(MainActivity.kt:65)

MainActivity

class MainActivity : AppCompatActivity()
 {

    var userService: UserService = ApiUtils.getUserService()
    var dotscount: Int = 0
    lateinit var sliderDotspanel: LinearLayout
    lateinit var sectionPagerAdapter: SectionPagerAdapter
    lateinit var respCategories: RespCategories
    var resp: RespCategories? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        sliderDotspanel = findViewById(R.id.sliderdots)
        fetchData()


    }


    fun fetchData() {

        var call: Call<RespCategories>

        call = userService.getData()

        call.enqueue(object : Callback<RespCategories> {
            override fun onFailure(call: Call<RespCategories>, t: Throwable) {
                Toast.makeText(this@MainActivity, "fail", Toast.LENGTH_LONG).show()
            }

            override fun onResponse(call: Call<RespCategories>, response: Response<RespCategories>) {
                Toast.makeText(this@MainActivity, "success", Toast.LENGTH_LONG).show()
                respCategories = response.body()!!
                var dataGenerator:DataGenerator
                dataGenerator=DataGenerator()
                dataGenerator.addData(respCategories)
              //  DataGenerator.addData(respCategories)
                showData()
            }

        })

    }

    fun showData(){

        //var resp:RespCategories=DataGenerator.getData()
        val model=ViewModelProviders.of(this).get(DataGenerator::class.java)
       // var resp=model.getData()

        model.d.observe(this, Observer<RespCategories> {
                r->resp=r
        })

        if (viewPager != null) {

            sectionPagerAdapter = SectionPagerAdapter(supportFragmentManager, resp)
            viewPager.adapter = sectionPagerAdapter

            dotscount = sectionPagerAdapter.getCount()
            var dots: Array<ImageView?>? = null
            dots = arrayOfNulls(dotscount)

            for (i in 0 until dotscount) {
                dots[i] = ImageView(this@MainActivity)
                dots[i]!!.setImageDrawable(ContextCompat.getDrawable(applicationContext, R.drawable.non_active_dots))

                val params = LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT)
                params.setMargins(8, 0, 8, 0)
                sliderDotspanel.addView(dots[i], params)
            }

            dots[0]!!.setImageDrawable(ContextCompat.getDrawable(applicationContext, R.drawable.active_dots))
            viewPager.addOnPageChangeListener(object : ViewPager.OnPageChangeListener {
                override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {

                }

                override fun onPageSelected(position: Int) {
                    for (i in 0 until dotscount) {
                        dots[i]!!.setImageDrawable(ContextCompat.getDrawable(applicationContext, R.drawable.non_active_dots))

                    }

                    dots[position]!!.setImageDrawable(ContextCompat.getDrawable(applicationContext, R.drawable.active_dots))

                }

                override fun onPageScrollStateChanged(state: Int) {

                }
            })
        }

    }
}
>Datagenerator
````````````
class DataGenerator constructor(): ViewModel() {

    companion object {
       // lateinit var da:RespCategories
    //   lateinit var da:MutableLiveData<RespCategories>
    }

            val d=MutableLiveData<RespCategories>()

    fun addData(respCategories: RespCategories){
       // d=respCategories
        d.value=respCategories

    }
    fun getData():MutableLiveData<RespCategories>{
        return d
    }
}
>RespCategories
````````````
data class RespCategories constructor(

    @field:SerializedName("type")
    val type: String? = null,

    @field:SerializedName("value")
    val value: List<String?>? = null


)

  [1]: https://i.stack.imgur.com/eDAhx.png

回答1:

There is mistake in your code: your observer in showData() observe for one DataGenerator object, but onResponse() callback post data to another one. You should

Few words about type parameter nullability of LiveData. Look at Observer interface:

public interface Observer<T> {
    void onChanged(@Nullable T t);
}

parameter of onChanged() method is annotated with @Nullable. This method observe nullable type in depend of LiveData type parameter nullability. Even if your LiveData defined with non null type parameter, you can expect null:

  • if you call liveData.value on new object, but you can override default null value and set your own

    val d = MutableLiveData<RespCategories>().apply { value = RespCategories.DEFAULT }
    
  • if your java code post null value (it's not prohibited)

  • 发表于 2019-04-01 21:00
  • 阅读 ( 74 )
  • 分类:sof

条评论

请先 登录 后评论
不写代码的码农
小编

篇文章

作家榜 »

  1. 小编 文章
返回顶部
部分文章转自于网络,若有侵权请联系我们删除