I am learning dager2. And as for me i have not clear moment with interface and presenter. For example i have a project without dagger2.
MainActivity <- acitivty
MainView <- interface
MainPresenter <- class
I have realized interface MainView in MainActivity
MainActivity implements MainView {
onCreate(///) {
MainPresener mP = new MainPresenter(this)
mp.getData()
}
@overirde // method from interface
public void test(String test) {///}
}
My presenter
MainPresenter{
public void MainPresenter(MainView mainView) {///}
public void getData() {mainView.test("test")}
}
My interface
inreface MainView {
public void test(String test)
}
So, as for me everething is clear. When i used dagger2 i had a code like this:
interface UserView
interface UserView {
fun setData(data: String)
}
for a test i created two module
@Module
class HelpersModule {
@Provides
fun provideUserHelper(): UserHelper {
return UserHelper()
}
@Provides
fun provideGeneralHelper(): GeneralHelpers {
return GeneralHelpers()
}
}
and
@Module
class UserModule {
@Provides
fun provideUserPresenter(userHelper: UserHelper,
generalHelpers: GeneralHelpers): UserPresenter {
return UserPresenter(userHelper, generalHelpers)
}
also i had AppComponent
@Component(modules = arrayOf(UserModule::class, HelpersModule::class))
@Singleton
interface AppComponent {
// inject to ...
// activities
fun inject(activity: MainActivity)
}
My presenter
class UserPresenter(private val userHelper: UserHelper, private val generalHelpers: GeneralHelpers) {
private val TAG: String = UserPresenter::class.java.simpleName
fun getUser() {
Log.e(TAG, "getUser")
}
}
My activity
class MainActivity : AppCompatActivity(), UserView {
private var TAG: String = "MainActivity"
@Inject
lateinit var userPresenter: UserPresenter
override fun onCreate(savedInstanceState: Bundle?) {
// init app component, this activity
App.appComponent.inject(activity = this@MainActivity)
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
override fun onResume() {
super.onResume()
userPresenter.getUser()
}
override fun setData(data: String) {
Log.e(TAG, "data from presenter $data")
}
}
My question: How i can call methods from interface UserView in UserPresenter like this:
class UserPresenter(private val userHelper: UserHelper, private val generalHelpers: GeneralHelpers) {
private val TAG: String = UserPresenter::class.java.simpleName
fun getUser() {
Log.e(TAG, "getUser")
// call method from interface UserView, and display data in MainActivity
userView.setData("Alex, ${userHelper.getDefAge()} ${generalHelpers.generalHelper()}")
}
}
You will have to inject your view into the presenter either by using the DI framework or by manually setting the view.
Option 1
class UserPresenter(private val userHelper: UserHelper, private val generalHelpers: GeneralHelpers) {
private val TAG: String = UserPresenter::class.java.simpleName
lateinit var userView: UserView
fun getUser() {
Log.e(TAG, "getUser")
userView.setData("Alex, ${userHelper.getDefAge()} ${generalHelpers.generalHelper()}")
}
}
Call onCreate() in your Activity
presenter.userView = this
Option 2
You will have to create another module preferably an interface or an abstract class to include in your UserModule. Dagger doesn't know how to provide the UserView, so we need to instruct the DI how-to. Change to Presenter's constructor:
class UserPresenter(private val userHelper: UserHelper, private val generalHelpers: GeneralHelpers, private va userView: UserView ) {
private val TAG: String = UserPresenter::class.java.simpleName
fun getUser() {
Log.e(TAG, "getUser")
userView.setData("Alex, ${userHelper.getDefAge()} ${generalHelpers.generalHelper()}")
}
}
@Module
abstract class UserViewModule {
@Binds
abstract fun bindUserView(activity: MainActivity): UserView
}
...
// in your UserModule
@Module(includes = [UserViewModule::class])
class UserModule {
...
}
I think you might be able to simplify the above using one module if Dagger knows how to provide the rest of presenter's dependencies. Get rid of UserModule in favor of UserViewModule.