gpt4 book ai didi

android - 深层链接空字符串参数

转载 作者:行者123 更新时间:2023-12-05 00:02:05 24 4
gpt4 key购买 nike

我正在使用 Jetpack Navigation作为我的应用程序中的导航解决方案。
我在使用 generated safe args 时遇到了不一致的行为与深度链接策略相反。
假设我有以下导航图:

<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
app:startDestination="@+id/home_dest">

<fragment
android:id="@+id/home_dest"
android:name="com.example.android.codelabs.navigation.HomeFragment"
android:label="@string/home"
tools:layout="@layout/home_fragment" >
<action
android:id="@+id/action_home_dest_to_deeplink_dest"
app:destination="@id/deeplink_dest" />
</fragment>

<fragment
android:id="@+id/deeplink_dest"
android:name="com.example.android.codelabs.navigation.DeepLinkFragment"
android:label="@string/deeplink"
tools:layout="@layout/deeplink_fragment">

<argument
android:name="myarg"
app:argType="string" />

<deepLink app:uri="example://my-deelink-frag?myArg={myarg}" />
</fragment>
</navigation>
我已经定义了两种导航到 DeepLinkFragment 的方法。 :
  • ID 为 action_home_dest_to_deeplink_dest 的导航操作
  • 一个深度链接 example://my-deelink-frag?myArg={myarg}

  • DeepLinkFragment我正在使用 navArgs()反序列化传入 Bundle 的函数并显示一个简单的 Toast信息。
    class DeepLinkFragment : Fragment() {

    private val args : DeepLinkFragmentArgs by navArgs()

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    Toast.makeText(requireContext(), args.myarg, Toast.LENGTH_SHORT).show()
    }
    }
    使用 generated safe args 导航时我可以发送一个空字符串作为 myArg 的值.
    没问题。
    findNavController().navigate(HomeFragmentDirections.actionHomeDestToDeeplinkDest(""))
    但是,当通过深度链接方式使用空字符串作为参数进行导航时:
    val arg = ""
    findNavController().navigate("example://my-deelink-frag?myArg=${arg}".toUri())
    我得到以下堆栈跟踪:
     Caused by: java.lang.IllegalArgumentException: Required argument "myarg" is missing and does not have an android:defaultValue
    at com.example.android.codelabs.navigation.DeepLinkFragmentArgs$Companion.fromBundle(DeepLinkFragmentArgs.kt:29)
    at com.example.android.codelabs.navigation.DeepLinkFragmentArgs.fromBundle(Unknown Source:2)
    at java.lang.reflect.Method.invoke(Native Method) 
    at androidx.navigation.NavArgsLazy.getValue(NavArgsLazy.kt:52) 
    at androidx.navigation.NavArgsLazy.getValue(NavArgsLazy.kt:34) 
    at com.example.android.codelabs.navigation.DeepLinkFragment.getArgs(DeepLinkFragment.kt:30) 
    at com.example.android.codelabs.navigation.DeepLinkFragment.onViewCreated(DeepLinkFragment.kt:34) 
    at androidx.fragment.app.Fragment.performViewCreated(Fragment.java:2987) 
    at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:546) 
    at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:282) 
    at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:2189) 
    at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:2106) 
    at androidx.fragment.app.FragmentManager.execPendingActions(FragmentManager.java:2002) 
    at androidx.fragment.app.FragmentManager$5.run(FragmentManager.java:524) 
    at android.os.Handler.handleCallback(Handler.java:938) 
    at android.os.Handler.dispatchMessage(Handler.java:99) 
    at android.os.Looper.loop(Looper.java:233) 
    at android.app.ActivityThread.main(ActivityThread.java:8068) 
    at java.lang.reflect.Method.invoke(Native Method) 
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:631) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:978) 
    来自生成的 DeeplinkFragmentArgs代码
    public data class DeepLinkFragmentArgs(
    public val myarg: String = ""
    ) : NavArgs {
    public fun toBundle(): Bundle {
    val result = Bundle()
    result.putString("myarg", this.myarg)
    return result
    }

    public companion object {
    @JvmStatic
    public fun fromBundle(bundle: Bundle): DeepLinkFragmentArgs {
    bundle.setClassLoader(DeepLinkFragmentArgs::class.java.classLoader)
    val __myarg : String?
    if (bundle.containsKey("myarg")) {
    __myarg = bundle.getString("myarg")
    if (__myarg == null) {
    throw IllegalArgumentException("Argument \"myarg\" is marked as non-null but was passed a null value.")
    }
    } else {
    __myarg = ""
    }
    return DeepLinkFragmentArgs(__myarg)
    }
    }
    }

    Looking at the code it seems as if an empty string is making the bundle.getString("myarg") return null instead of the empty string?!


    作为修复,我可以添加 android:defaultValue .
    但是我认为这不是正确的解决方案。
    <argument
    android:name="myarg"
    android:defaultValue=""
    app:argType="string" />
    这是使用深度链接时的已知限制吗?

    最佳答案

    不确定这是否完全回答了您的问题,但您所做的一切看起来都是正确的。以下是根据我自己的经验的一些相关说明。
    内部链接
    我可能会使用 SafeArgs 在应用程序内部进行导航,或者直接调用 findNavController.navigatethis code of mine .就我个人而言,我不太喜欢更多的 Android XML 标记。
    外部链接
    如果您希望链接来自电子邮件等来源,那么深度链接选项是最合适的,但您还需要验证输入。正如您似乎指出的那样,一个空的默认值本身可能是不够的。
    因此,在使用 DeepLinkFragmentArgs 之前,我会确保您获得所需的控制。例如,在过去,我有时发现在允许导航继续之前进行验证很有用 - 例如,首先在 Forwarder Activity 中接收深层链接。 .这意味着我可以阻止在 Chrome 自定义选项卡位于最顶层时执行深层链接(因为这会导致诸如重新创建主要 Activity 之类的问题)。
    移动深度链接
    顺便说一句,我发现 gmail 等电子邮件客户端可能不允许自定义 URI 方案深层链接,所以我的示例使用 Android https applinks ,以防万一您对此感兴趣。

    关于android - 深层链接空字符串参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70925235/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com