我正在用Dagger2为DI做一个项目,在MVP架构中注入presenter。我在MVP架构中注入了presenter,但不知为何,当我构建应用程序时,它以错误的方式崩溃了:"lateinit属性presenter has not been initialized"。我知道这意味着没有注入,但我不明白为什么。下面是我的代码。
APPLICATION CLASS
class FlowerApp : Application() {
override fun onCreate() {
super.onCreate()
initAppComponent()
}
private fun initAppComponent() {
appComponent = DaggerAppComponent
.builder()
.appModule(AppModule(this))
.build()
}
companion object {
lateinit var appComponent: AppComponent
}
}
ホームモードル
@Module
class HomeModule(var homeFragment: HomeContract.View) {
@Provides
fun providePresenter(homeInteractor: HomeInteractor): HomePresenter {
return HomePresenter(homeFragment, homeInteractor)
}
@Provides
fun provideInteractor(): HomeInteractor {
return HomeInteractor()
}
}
附录
@Component(
modules = [
(AppModule::class),
(NetworkModule::class),
(HomeModule::class)
]
)
interface AppComponent {
fun inject(application: FlowerApp)
fun inject(homeFragment: HomeContract.View)
}
家纺
class HomeFragment : Fragment(), HomeContract.View {
@Inject
lateinit var presenter: HomePresenter
private lateinit var flowerAdapter: FlowerAdapter
private var startingPage = 1
private var recyclerStartPos = 0
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_home, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
setAdapter()
presenter.getFlowers(startingPage)
setListeners()
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
FlowerApp.appComponent.inject(this)
}
如果需要其他代码信息就问吧......
编辑:logcat错误。
2020-06-06 22:12:37.513 13401-13401? EAndroidRuntime。FATAL EXCEPTION: main Process: element.list.flowermvp, PID: 13401 kotlin.UninitializedPropertyAccessException: lateinit property presenter has not been initialized at element.list.flowermvp.home.HomeFragment.onViewCreated(HomeFragment.kt:37) at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl. java:892) at androidx.fragment.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManagerImpl.java:1238) at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:1303) at androidx.fragment.app.BackStackRecord.executeOps(BackStackRecord.java:439) at androidx.fragment.app.BackStackRecord.executeOps(BackStackRecord.java:439)。 fragment.app.FragmentManagerImpl.executeOps(FragmentManagerImpl.java:2079) at androidx.fragment.app.FragmentManagerImpl.executeOpsTogether(FragmentManagerImpl.java:1869) at androidx.fragment.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManagerImpl.java:1824) at androidx.fragment.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManagerImpl.java:1824) at androidx.fragment.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManagerImpl.java:1824). FragmentManagerImpl.execPendingActions(FragmentManagerImpl.java:1727) at androidx.fragment.app.FragmentManagerImpl.dispatchStateChange(FragmentManagerImpl.java:2663) at androidx.fragment.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManagerImpl.java:2613) at androidx.fragment.app.FragmentController. dispatchActivityCreated(FragmentController.java:246) at androidx.fragment.app.FragmentActivity.onStart(FragmentActivity.java:542) at androidx.appcompat.app.AppCompatActivity.onStart(AppCompatActivity.java:201) at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1392) at android.app.App.Activity.onStart(Activity.callActivityOnStart) at android.app.App.App.App.Activity.onStart(Activity.callActivityOnStart)。 Activity.performStart(Activity.java:7252) at android.app.ActivityThread.handleStartActivity(ActivityThread.java:2970) at android.app.servertransaction.TransactionExecutor.performLifecycleSequence(TransactionExecutor.java:180) at android.app.servertransaction.TransactionExecutor.cycleToPath(TransactionExecutor. java:165) at android.app.servertransaction.TransactionExecutor.executor.executeLifecycleState(TransactionExecutor.java:142) at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:70) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1831) at android.os.Handler.dispatchMessage(Handler. java:106) at android.os.Looper.loop(Looper.java:201) at android.app.ActivityThread.main(ActivityThread.java:6806) at java.lang.reflect.Method. invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:547) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:873)
你正在尝试注入在项目中提供的presenter。HomeModule
通过应用程序的主组件来实现。这样做是行不通的,因为你从来没有向应用程序提供过 HomeModule
对你的 AppComponent
. HomeModule
甚至不应该是一个部分的 AppComponent
因为它所提供的东西(presenter和interactor)只有在片段存在时才会存在,这意味着它们存在于片段作用域,而不是应用程序作用域。
你需要做的是创建另一个组件,将其注入到你的片段中,例如,在你的片段中,你可以创建一个新的组件。
@Component(
modules = [
(HomeModule::class)
]
)
interface HomeComponent {
fun inject(homeFragment: HomeFragment)
}
然后在你的 HomeFragment
:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
DaggerHomeComponent
.builder()
.homeModule(HomeModule(this))
.build()
.inject(this)
}
如果你需要来自应用范围的东西(来自网络和应用模块),那么你可以通过以下方式注入它们 AppComponent
就像你之前做的那样。
我觉得问题出在 var homeFragment: HomeContract.View
在你的HomeModule中。 我建议你重写HomePresenter,并将通过构造函数传递HomeFragment替换为方法bindViewunbindView。
class HomePresenter(private val interactor: HomeInteractor) {
var view: HomeView? = null
fun bindView(view: HomeView) {
this.view = view
}
fun unbindView() {
view = null
}
}
在presenter中存储fragment引用可能会导致内存泄漏和null-pointer异常,在Fragment被销毁而presenter没有被销毁的情况下。
在你的组件中,你没有注入 HomeFragment
但基类(HomeContract.View
). 意思是说,Dagger不会注入属性的 HomeFragment
不在基类中。
我认为问题在于,你没有注入 HomeFragment
在AppCoponent中增加一个扩展方法
@Component(
modules = [
(AppModule::class),
(NetworkModule::class),
(HomeModule::class)
]
)
interface AppComponent {
fun inject(application: FlowerApp)
fun inject(homeFragment: HomeContract.View)
}
fun HomeFragment.inject(){
FlowApp.appComponent.inject(this)
}
注入HomeFragment
override fun onAttach(context: Context) {
super.onAttach(context)
inject()
}