You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Compose中Navigation抛出Illegal Argument错误的原因排查

Compose导航点击菜单崩溃问题解决

问题现象

在Compose中实现页面导航,导航逻辑定义在navigation.kt的Nav()函数中,通过give_route()匹配路由(匹配成功返回对应路由,否则返回page_not_found路由),路由字符串存于Address.kt密封类,页面Composable函数在Views/Pages.kt中。

运行时Feed页面正常显示,下拉菜单可展开,但点击菜单中任意按钮后应用崩溃,抛出如下错误:

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.<company_name.<app_name>, PID: 20633
    java.lang.IllegalArgumentException: Navigation destination that matches request NavDeepLinkRequest{ uri=android-app://androidx.navigation/New - Audio } cannot be found in the navigation graph NavGraph(0x0) startDestination={Destination(0x78c8aacb) route=Feed}
    ...[省略部分日志]
I/Process: Sending signal. PID: 20633 SIG: 9

相关代码

package com.<company_name.<app_name>

import androidx.compose.runtime.Composable
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
import com.<company_name.<app_name>


// Class For function needed for Navigation

@Composable
fun Nav() {
    val navController = rememberNavController()

    NavHost(navController = navController, startDestination = Address.Feed.route) {

        composable(Address.Feed.route)
        {
            feed(
                Navi = {add -> navController.navigate(give_route(add))}
            )

        }

    }


}


fun give_route(title: String): String {
    return when (title) {
        "Feed" -> Address.Feed.route
        "Question" -> Address.Question.route
        "Notice" -> Address.Notice.route
        "Status" -> Address.Status.route
        "DM" -> Address.DM.route
        "Chat" -> Address.Chat.route
        "Group_chat" -> Address.Group_chat.route
        "Notify" -> Address.Notify.route
        "Search" -> Address.Search.route
        "Profile" -> Address.Profile.route
        "Profile-Pvt" -> Address.Profile_Pvt.route
        "Profile-User" -> Address.Profile_User.route
        "Ratting" -> Address.Ratting.route
        "New - Text" -> Address.New_Text.route
        "New - Image" -> Address.New_Image.route
        "New - Video" -> Address.New_Video.route
        "New - Audio" -> Address.New_Audio.route
        "New - Other" -> Address.New_File.route
        else -> Address.page_not_found.route

    }
}

Address.kt

package com.<company_name.<app_name>

sealed class Address(val route: String) {

    object Feed : Address("Feed")
    object Question : Address("Question")
    object Notice : Address("Notice")
    object Status : Address("Status")
    object DM : Address("DM")
    object Chat : Address("Chat")
    object Group_chat : Address("Group_chat")
    object Notify : Address("Notify")
    object Search : Address("Search")
    object Profile : Address("Profile")
    object Profile_Pvt : Address("Profile-Pvt")
    object Profile_User : Address("Profile-User")
    object Ratting : Address("Ratting")
    object New_Text : Address("New - Text")
    object New_Image : Address("New - Image")
    object New_Video : Address("New - Video")
    object New_Audio : Address("New - Audio")
    object New_File : Address("New - File")
    object page_not_found : Address("Page not found")


}

MainActivity.kt

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            AppTheme {
                // A surface container using the 'background' color from the theme
                Surface(
                    modifier = Modifier.fillMaxSize(),
                    color = MaterialTheme.colorScheme.background
                ) {
                    Nav()
                }
            }
        }
    }
}

Pages.kt

package com.<company_name.<app_name>


import androidx.compose.foundation.layout.Row
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.rounded.*
import androidx.compose.material3.*
import androidx.compose.runtime.*

// PAGE VIEWS


// Feed View
@Composable
fun feed(Navi: (String) -> Unit) {

    var newPost by remember { mutableStateOf(false) } // TODO - y

    Row() {
        FilledTonalIconButton(
            onClick = { newPost = true },
            enabled = true
        ) {
            Icon(
                Icons.Rounded.Add,
                "Button for creating a new post. " +
                        "Opens the Menu to selct the type for your new post"
            )
        }

        DropdownMenu(
            expanded = newPost,
            onDismissRequest = { newPost = false }
        ) {
            DropdownMenuItem(
                text = { Text("Text") },
                onClick = { Navi("New - Text") },
                enabled = true,
                leadingIcon = {
                    Icon(Icons.Rounded.ViewHeadline,
                        "To Post Text"
                    )
                }
            )

            DropdownMenuItem(
                text = { Text("Image") },
                onClick = { Navi("New - Image") },
                enabled = true,
                leadingIcon = {
                    Icon(Icons.Rounded.Wallpaper,
                        "To Post Image"
                    )
                }
            )

            DropdownMenuItem(text = { Text("Video") },
                onClick = { Navi("New - Video") },
                enabled = true,
                leadingIcon = {
                    Icon(Icons.Rounded.Slideshow,
                        "To Post Video"
                    )
                }
            )

            DropdownMenuItem(text = { Text("Audio") },
                onClick = { Navi("New - Audio") },
                enabled = true,
                leadingIcon = {
                    Icon(Icons.Rounded.SpatialAudioOff,
                        "To Post Audio"
                    )
                }
            )

            DropdownMenuItem(text = { Text("Other") },
                onClick = { Navi("New - Other") },
                enabled = true,
                leadingIcon = {
                    Icon(Icons.Rounded.PostAdd,
                        "To open custom file window for posting user file"
                    )
                }
            )
        }
    }
}



@Composable
fun New_Text() {
    Text("a")
}


@Composable
fun New_Image() {
    Text("b")
}


@Composable
fun New_Video() {
    Text("c")
}



@Composable
fun New_Audio() {
    Text("d")
}


@Composable
fun New_File() {
    Text("e")
}

问题原因与解决方案

原因

崩溃的核心原因是导航图(NavHost)中只注册了Feed页面的路由,其他页面的路由没有添加到导航图中。当调用navController.navigate()跳转到其他路由时,Navigation组件找不到对应的目的地,因此抛出IllegalArgumentException。

解决方案

在Nav()函数的NavHost中,为所有需要导航到的页面添加对应的composable节点。

修改后的navigation.kt代码如下:

package com.<company_name.<app_name>

import androidx.compose.runtime.Composable
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
import com.<company_name.<app_name>

@Composable
fun Nav() {
    val navController = rememberNavController()

    NavHost(navController = navController, startDestination = Address.Feed.route) {
        // Feed页面
        composable(Address.Feed.route) {
            feed(Navi = { add -> navController.navigate(give_route(add)) })
        }
        // 新增所有需要导航的页面节点
        composable(Address.New_Text.route) {
            New_Text()
        }
        composable(Address.New_Image.route) {
            New_Image()
        }
        composable(Address.New_Video.route) {
            New_Video()
        }
        composable(Address.New_Audio.route) {
            New_Audio()
        }
        composable(Address.New_File.route) {
            New_File()
        }
        // 其他页面同理,需要导航的都要添加对应的composable
        composable(Address.Question.route) {
            // 这里替换为对应的Question页面Composable
        }
        composable(Address.Notice.route) {
            // 这里替换为对应的Notice页面Composable
        }
        // ... 其他路由节点依次添加
        composable(Address.page_not_found.route) {
            // 可以添加404页面的Composable
        }
    }
}

fun give_route(title: String): String {
    return when (title) {
        "Feed" -> Address.Feed.route
        "Question" -> Address.Question.route
        "Notice" -> Address.Notice.route
        "Status" -> Address.Status.route
        "DM" -> Address.DM.route
        "Chat" -> Address.Chat.route
        "Group_chat" -> Address.Group_chat.route
        "Notify" -> Address.Notify.route
        "Search" -> Address.Search.route
        "Profile" -> Address.Profile.route
        "Profile-Pvt" -> Address.Profile_Pvt.route
        "Profile-User" -> Address.Profile_User.route
        "Ratting" -> Address.Ratting.route
        "New - Text" -> Address.New_Text.route
        "New - Image" -> Address.New_Image.route
        "New - Video" -> Address.New_Video.route
        "New - Audio" -> Address.New_Audio.route
        "New - Other" -> Address.New_File.route
        else -> Address.page_not_found.route
    }
}

这样修改后,所有需要导航的路由都在NavHost中注册了对应的目的地,点击菜单按钮时就能正常跳转,不会再出现崩溃。

内容的提问来源于stack exchange,提问作者user20603322

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 23:50:28