Kotlin Android MVP + Dagger 2 lateinit 属性 presenter 尚未初始化
Kotlin Android MVP + Dagger 2 lateinit property presenter has not been initialized
尝试在 Android 上将 Dagger 与 Kotlin 结合使用。并得到异常:
Caused by: kotlin.UninitializedPropertyAccessException: lateinit property presenter has not been initialized
at com.ad.eartquakekotlin.main.MainFragment.onViewCreated(MainFragment.kt:43)
at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManager.java:1471)
at androidx.fragment.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1784)
at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManager.java:1852)
at androidx.fragment.app.BackStackRecord.executeOps(BackStackRecord.java:802)
at ...
该应用程序专门用于测试。我得到地震并在设备屏幕上显示它们。
我想要的只是
1.在我的片段中注入演示者(视图)
2. 在我的presenter
中注入api
这是我项目的结构:
那里有两个模块和组件,如您所见:
@Module
class ApplicationModule(private val application: Application) {
@Provides
@Singleton
fun provideApplication():Application = application
}
@Module
class MainModule (private val view: MainContract.View) {
@Provides
fun provideView(): MainContract.View {
return view
}
@Provides
fun providePresenter(): MainContract.Presenter {
return MainPresenter(view)
}
}
和组件:
@Component(modules = [ApplicationModule::class])
interface ApplicationComponent {
fun inject(application: Application)
fun plus (mainModule: MainModule) : MainComponent
}
和
@Subcomponent(modules = [MainModule::class])
interface MainComponent {
fun inject (view : MainContract.View)
}
有合同:
interface MainContract {
interface View {
fun showLoading()
fun hideLoading()
fun showMessage(message: String)
fun showData(data: EarthquakeRootObject)
}
interface Presenter {
fun onDestroy()
fun loadData()
}
}
申请class:
class MainApp: Application() {
companion object {
lateinit var graph: ApplicationComponent
}
override fun onCreate() {
super.onCreate()
buildGraph()
}
private fun buildGraph() {
graph = DaggerApplicationComponent
.builder()
.applicationModule(ApplicationModule(this))
.build()
}
}
片段(我想使用注入的地方)
class MainFragment : Fragment(), MainContract.View {
private lateinit var earthquakesAdapter: EarthquakeRecyclerViewAdapter
private lateinit var earthquakes: EarthquakeRootObject
@Inject lateinit var presenter: MainContract.Presenter
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
return container?.inflate(R.layout.fragment_main)
}
override fun onAttach(context: Context?) {
super.onAttach(context)
MainApp.graph.plus(MainModule(this)).inject(this)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
earthquakesRecyclerView.layoutManager = LinearLayoutManager(context)
earthquakesRecyclerView.setHasFixedSize(true)
presenter.loadData()
}
还有我的主持人
class MainPresenter (var view: MainContract.View?) : MainContract.Presenter {
private var disposable: Disposable? = null
@Inject lateinit var api : EarthquakeApi
override fun onDestroy() {
disposable?.dispose()
view = null
}
override fun loadData() {
view?.showLoading()
disposable = api.getEarthquakes()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
{
response ->
view?.showData(response)
view?.hideLoading()
},
{
throwable ->
view?.showMessage(throwable.message ?: "Ошибка")
view?.hideLoading()
}
)
}
我做错了什么?
你需要更换
fun inject (view : MainContract.View)
和
fun inject(target : MainFragment)
尝试在 Android 上将 Dagger 与 Kotlin 结合使用。并得到异常:
Caused by: kotlin.UninitializedPropertyAccessException: lateinit property presenter has not been initialized
at com.ad.eartquakekotlin.main.MainFragment.onViewCreated(MainFragment.kt:43)
at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManager.java:1471)
at androidx.fragment.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1784)
at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManager.java:1852)
at androidx.fragment.app.BackStackRecord.executeOps(BackStackRecord.java:802)
at ...
该应用程序专门用于测试。我得到地震并在设备屏幕上显示它们。
我想要的只是 1.在我的片段中注入演示者(视图) 2. 在我的presenter
中注入api这是我项目的结构:
那里有两个模块和组件,如您所见:
@Module
class ApplicationModule(private val application: Application) {
@Provides
@Singleton
fun provideApplication():Application = application
}
@Module
class MainModule (private val view: MainContract.View) {
@Provides
fun provideView(): MainContract.View {
return view
}
@Provides
fun providePresenter(): MainContract.Presenter {
return MainPresenter(view)
}
}
和组件:
@Component(modules = [ApplicationModule::class])
interface ApplicationComponent {
fun inject(application: Application)
fun plus (mainModule: MainModule) : MainComponent
}
和
@Subcomponent(modules = [MainModule::class])
interface MainComponent {
fun inject (view : MainContract.View)
}
有合同:
interface MainContract {
interface View {
fun showLoading()
fun hideLoading()
fun showMessage(message: String)
fun showData(data: EarthquakeRootObject)
}
interface Presenter {
fun onDestroy()
fun loadData()
}
}
申请class:
class MainApp: Application() {
companion object {
lateinit var graph: ApplicationComponent
}
override fun onCreate() {
super.onCreate()
buildGraph()
}
private fun buildGraph() {
graph = DaggerApplicationComponent
.builder()
.applicationModule(ApplicationModule(this))
.build()
}
}
片段(我想使用注入的地方)
class MainFragment : Fragment(), MainContract.View {
private lateinit var earthquakesAdapter: EarthquakeRecyclerViewAdapter
private lateinit var earthquakes: EarthquakeRootObject
@Inject lateinit var presenter: MainContract.Presenter
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
return container?.inflate(R.layout.fragment_main)
}
override fun onAttach(context: Context?) {
super.onAttach(context)
MainApp.graph.plus(MainModule(this)).inject(this)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
earthquakesRecyclerView.layoutManager = LinearLayoutManager(context)
earthquakesRecyclerView.setHasFixedSize(true)
presenter.loadData()
}
还有我的主持人
class MainPresenter (var view: MainContract.View?) : MainContract.Presenter {
private var disposable: Disposable? = null
@Inject lateinit var api : EarthquakeApi
override fun onDestroy() {
disposable?.dispose()
view = null
}
override fun loadData() {
view?.showLoading()
disposable = api.getEarthquakes()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
{
response ->
view?.showData(response)
view?.hideLoading()
},
{
throwable ->
view?.showMessage(throwable.message ?: "Ошибка")
view?.hideLoading()
}
)
}
我做错了什么?
你需要更换
fun inject (view : MainContract.View)
和
fun inject(target : MainFragment)