androidkotlinandroid-mvp

on kotlin, textview not initialized outside onCreate method


I am new at Kotlin and trying to implement MVP Architecture,

Currently I am having problem initializing/setting textview's value outside onCreate() method here is my code

SplashActivity.kt

class SplashActivity : AppCompatActivity(), Splash.ViewInterface {
lateinit var appDetail: AppDetail
lateinit var textTitle: TextView

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

    textTitle = findViewById(R.id.splash_txt_title) as TextView

    AppSingleton.appContext = applicationContext

    var splashPresentation = SplashPresentation(this)
    splashPresentation.getAppDetailFromService()
}

override fun fetchAppDetailSuccessful(response: SplashServiceObject) {
    AppSingleton.initializeAppDetal(Gson().fromJson(response.json_string, AppDetail::class.java))
    this.appDetail = AppSingleton.appDetail
}

override fun fetchAppDetailFailed(errMsg: String) {
    textTitle.text = errMsg
}
}

SplashPresenter.kt

class SplashPresentation(private val view: Splash.ViewInterface) : Splash.PresentationInterface {

fun getAppDetailFromService() {
    var splashService = SplashService()
    splashService.getAppDetailFromAssets(this)
}

override fun fetchAppDetailFromServiceSuccessful(response: SplashServiceObject) {
    view.fetchAppDetailSuccessful(response)
}

override fun fetchAppDetailFromServiceFailed(errMsg: String) {
    view.fetchAppDetailFailed(errMsg)
}
}

SplashService.kt

 class SplashService {
fun getAppDetailFromAssets(splashPresentation: SplashPresentation) {
    val json_filename = "appdetail.json"
    var jsonResponse: JsonResponse = AppSingleton.commonUtils.fetchJsonFromAssets(json_filename, AppSingleton.appContext!!)
    if (jsonResponse.json_status) {
        var splashServiceObj = SplashServiceObject
        splashServiceObj.json_string = jsonResponse.json_info
        splashServiceObj.response_msg = "JSON Successful fetched."
        splashPresentation.fetchAppDetailFromServiceSuccessful(splashServiceObj)
    } else {
        splashPresentation.fetchAppDetailFromServiceFailed(jsonResponse.json_info)
    }
}
}

in my SplashActivity().onCreate(), I am calling a Presenter that access Service, then the Service return a value to Presenter,
Then Presenter, return value to my SplashActivity's View, one of the function is, fetchAppDetailFailed(errMsg)

when I run the app, it crashes, saying the "textaa" is not yet initialized.
back in Java exp, when the variable is already instantiated on onCreate(), you can call this variable anywhere within the activity.

Thanks in advance!


Solution

  • You cannot instantiate Activities on Android. They are instantiated by the OS, and the OS calls the lifecycle methods on it.

    In an MVP pattern, the View and Presenter both reference each other. Since Activity (the View) is the entry point of the application, your Activity should instantiate the Presenter and pass a reference of itself to the Presenter so communication can go both ways.

    Also, the reference to the activity in the Presenter should be specified as a ViewInterface, not an Activity, or you're kind of defeating the purpose of using MVP.

    class SplashPresentation(private val view: Splash.ViewInterface) : Splash.PresentationInterface {
    
        //... methods that call functions on view
    }
    
    class SplashActivity : AppCompatActivity(), Splash.ViewInterface {
    
        private val presenter = SplashPresentation(this)
    
        //...
    
    }