首页 > 解决方案 > Android: Fragment has null arguments when getting global nested safeargs

问题描述

I am trying to get my safeargs within the second fragment (calibrateRepairOptionFragment) of my nested_graph, The problem is that I get the above written error Fragment CalibrateRepairOptionFragment{5e1268d} (c7c2906d-5a17-4d22-b41d-eefe8eee059f) id=0x7f09012d} has null arguments.

I am confused because when I try to get my safeargs in the first fragment (CalibrateRepairMessageFragment), everything works and the toolbar_title is not null.

BaseFragment (getting safeargs here)

abstract class NewBaseEmailFragment<out VB: ViewDataBinding>(
    private val layout: Int,
    private val next: Int,
) : Fragment(layout) {
    abstract val viewModel: ViewModel
    private val toolbarTitleArgs by navArgs<NavSendEmailArgs>()

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? = DataBindingUtil.inflate<VB>(inflater, layout, container, false).apply {
        lifecycleOwner = viewLifecycleOwner
        setVariable(BR.viewModel, viewModel)
    }.root

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        initToolbar()
    }

    // Using safeargs here, everything fine in the first fragment of the nested graph
    private fun initToolbar() = with(toolbar) {
        setupWithNavController(findNavController(), AppBarConfiguration(findNavController().graph))
        toolbar_title.text = toolbarTitleArgs.toolbarTitle
    }
}

First Fragment (no error here, toolbar is set correctly)

@AndroidEntryPoint
class CalibrateRepairMessageFragment : NewBaseEmailFragment<FragmentCalibrateRepairUserDataBinding>(
    R.layout.fragment_calibrate_repair_message,
    R.id.action_calibrateRepairMessageFragment_to_calibrateRepairOptionFragment,
 ) {
    override val viewModel: EmailViewModel by navGraphViewModels(R.id.nav_send_email) { defaultViewModelProviderFactory }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
    }
}

Second Fragment (getting error here, toolbar.title is null)

@AndroidEntryPoint
class CalibrateRepairOptionFragment : NewBaseEmailFragment<FragmentCalibrateRepairOptionBinding>(
    R.layout.fragment_calibrate_repair_option,
    R.id.action_calibrateRepairOptionFragment_to_calibrateRepairUserDataFragment,
) {
    override val viewModel: EmailViewModel by navGraphViewModels(R.id.nav_send_email) { defaultViewModelProviderFactory }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
    }
}

nav_main.xml

<!-- Sending arguments from homeFragment to nested Graph "nav_send_email" -->
<fragment
    android:id="@+id/homeFragment"
    android:name="com.example.app.framework.ui.view.fragments.home.HomeFragment"
    tools:layout="@layout/fragment_home">

    <action
        android:id="@+id/action_homeFragment_to_nav_send_email"
        app:destination="@id/nav_send_email">
    </action>
</fragment>
<!-- NESTED GRAPH "nav_send_mail" --->
<navigation
    android:id="@+id/nav_send_email"
    app:startDestination="@id/calibrateRepairMessageFragment">
    <!-- Global argument for entire nested graph -->
    <argument
        android:name="toolbar_title"
        app:argType="string"
        app:nullable="false" />

    <!-- Getting safeargs here is no problem! (first fragment) -->
    <fragment
        android:id="@+id/calibrateRepairMessageFragment"
        android:name="com.example.app.framework.ui.view.fragments.home.calibrateAndRepair.CalibrateRepairMessageFragment"
        tools:layout="@layout/fragment_calibrate_repair_message">
        <argument
            android:name="toolbar_title"
            app:argType="string"
            app:nullable="false" />
        <action
            android:id="@+id/action_calibrateRepairMessageFragment_to_calibrateRepairOptionFragment"
            app:destination="@id/calibrateRepairOptionFragment" />
    </fragment>

    <!-- Can't get safeargs here, safeargs is null (second fragment) -->
    <fragment
        android:id="@+id/calibrateRepairOptionFragment"
        android:name="com.example.app.framework.ui.view.fragments.home.calibrateAndRepair.CalibrateRepairOptionFragment"
        tools:layout="@layout/fragment_calibrate_repair_data_overview">
        <action
            android:id="@+id/action_calibrateRepairOptionFragment_to_calibrateRepairUserDataFragment"
            app:destination="@id/calibrateRepairUserDataFragment" />
    </fragment>
   
</navigation>

Full Stracktrace

 java.lang.IllegalStateException: Fragment CalibrateRepairOptionFragment{5e1268d} (c7c2906d-5a17-4d22-b41d-eefe8eee059f) id=0x7f09012d} has null arguments
        at com.example.app.framework.ui.view.fragments.home.refactor.NewBaseEmailFragment$$special$$inlined$navArgs$1.invoke(FragmentNavArgsLazy.kt:42)
        at com.example.app.framework.ui.view.fragments.home.refactor.NewBaseEmailFragment$$special$$inlined$navArgs$1.invoke(Unknown Source:0)
        at androidx.navigation.NavArgsLazy.getValue(NavArgsLazy.kt:44)
        at androidx.navigation.NavArgsLazy.getValue(NavArgsLazy.kt:34)
        at com.example.app.framework.ui.view.fragments.home.refactor.NewBaseEmailFragment.getToolbarTitleArgs(Unknown Source:4)
        at com.example.app.framework.ui.view.fragments.home.refactor.NewBaseEmailFragment.initToolbar(NewBaseEmailFragment.kt:59)
        at com.example.app.framework.ui.view.fragments.home.refactor.NewBaseEmailFragment.onViewCreated(NewBaseEmailFragment.kt:47)
        at com.example.app.framework.ui.view.fragments.home.calibrateAndRepair.CalibrateRepairOptionFragment.onViewCreated(CalibrateRepairOptionFragment.kt:23)
        at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:332)
        at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1199)
        at androidx.fragment.app.FragmentManager.addAddedFragments(FragmentManager.java:2236)
        at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:2009)
        at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:1965)
        at androidx.fragment.app.FragmentManager.execPendingActions(FragmentManager.java:1861)
        at androidx.fragment.app.FragmentManager$4.run(FragmentManager.java:413)
        at android.os.Handler.handleCallback(Handler.java:883)
        at android.os.Handler.dispatchMessage(Handler.java:100)
        at android.os.Looper.loop(Looper.java:214)
        at android.app.ActivityThread.main(ActivityThread.java:7356)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)

标签: androidkotlinandroid-architecture-navigationdagger-hiltandroid-safe-args

解决方案


您可以通过设置默认参数来避免空参数错误,并且您需要在使用它之前检查参数(无论是期望值还是默认值)

谢谢


推荐阅读