【问题标题】:Activity's TextView is nullActivity 的 TextView 为空
【发布时间】:2019-07-04 11:06:12
【问题描述】:

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

应用程序非常简单,只有一个活动,布局根据用户选择的位置显示不同的数据。在启动活动时,这会初始化onCreate中的presenter,并调用启动请求过程的方法。当我带着答案返回我的活动时,我试图在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.
    }
}

【问题讨论】:

  • 向我们展示您的进口产品
  • 抱歉...已添加进口!

标签: android kotlin nullpointerexception textview retrofit


【解决方案1】:

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

其次,将下面的这些行移到onStart()

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

我想推荐你在presenter中使用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 用于一个小项目。

【讨论】:

  • 不起作用..我得到数据。我的意思是,天气数据正在进入我的活动。但视图仍然为空。感谢您提供有关安全通话的信息​​。我正在使用!只是因为我相信那是正确的方式。但在你回答之后,我读到了。
猜你喜欢
  • 1970-01-01
  • 2021-06-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-19
  • 2013-01-07
相关资源
最近更新 更多