活动的TextView为null

时间:2019-02-10 23:52:55

标签: android kotlin nullpointerexception textview retrofit

我正在尝试制作一个应用,使用OpenWeatherMapKotlinRetrofitMVPthe clean architecture来检查天气。

该应用程序非常简单,只有一个活动,并且布局根据用户选择的位置显示不同的数据。启动活动时,这将初始化onCreate中的演示者,并调用启动请求过程的方法。当我返回带有答案的活动时,我试图在TextView中显示有关该响应的一些信息,但由于该视图为null,应用程序崩溃。

我正在使用Kotlin Android Extensions,从理论上讲,它允许我仅使用其ID调用视图,而无需使用findViewById

我是Kotlin的新手,也许我错过了一些东西。

import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import com.climaconsulta.R
import com.climaconsulta.user.model.pojos.MainWeather
import com.climaconsulta.user.presenter.MainActivityPresenter
import com.climaconsulta.user.presenter.MainActivityPresenterImpl
import kotlinx.android.synthetic.main.activity_main.*

class MainActivity : AppCompatActivity(), MainActivityView {
    var presenter: MainActivityPresenter? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        presenter = MainActivityPresenterImpl()
        presenter!!.getMainWeather("London")
    }

    override fun showCurrentCity() {
        presenter!!.getCurrentCity()
    }

    override fun showMainWeather(mainWeather: MainWeather) {
        mainTemperature.text = mainWeather.main!!.temp.toString()
        // HERE I TRY TO SET THE TEXT. BUT "mainTemperature" IS NULL
    }

    override fun showFiveDaysWeather(cityName: String) {
        presenter!!.getFiveDaysWheather(cityName)
    }

    override fun showError(error: String) {
        TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
    }
}

1 个答案:

答案 0 :(得分:1)

首先,为什么要强制可为空的类型以自行运行?为什么不像presenter?.func()这样的安全方式调用它? 强制调用将使您的应用崩溃,但安全调用-不会。

其次,将以下几行移至onStart()

presenter = MainActivityPresenterImpl()
presenter?.getMainWeather("London")
  

我建议您在演示者MainActivityView中使用   实现MainActivity的接口。我什么时候看   放入presenter

示例->

BasePresenter:

abstract class BasePresenter<View : BaseView> {
    protected var view: View? = null

    open fun attachView(view: View) {
        this.view = view
    }

    open fun detachView(view: View) {
        if (this.view == view) {
            this.view = null
        }
    }
}

interface BaseView {
    fun showError(error: String)
}

演示者:

class MainPresenter() : BasePresenter<MainActivityView>() {
    private fun getMainWeather(name: String) {
        view?.showProgress(true)
        ...
    }
}

MainActivity:

@Inject
protected lateinit var presenter: MainPresenter
...

override fun onStart() {
    super.onStart()
    presenter.attachView(this)
}

override fun onStop() {
    presenter.detachView(this)
    super.onStop()
}

是的,我使用 Dagger 2 提供依赖项。您可能会很伤心地使用它:

presenter = MainActivityPresenterImpl()
presenter?.getMainWeather("London")

但是,如果您愿意,您可以考虑为一个小型项目使用简单的Dagger 2 implementation