Dagger2 Android DI - lateinit属性没有被初始化。

问题描述 投票:0回答:1

我正在用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)

android dagger-2
1个回答
2
投票

你正在尝试注入在项目中提供的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 就像你之前做的那样。


0
投票

我觉得问题出在 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没有被销毁的情况下。


0
投票

在你的组件中,你没有注入 HomeFragment但基类(HomeContract.View). 意思是说,Dagger不会注入属性的 HomeFragment 不在基类中。


0
投票

我认为问题在于,你没有注入 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()
}
© www.soinside.com 2019 - 2024. All rights reserved.