Jetpack Glance小部件打开应用程序上点击有时会导致崩溃,当它不是,backstack是空的



我知道这不是世界上最好的标题,但让我先解释一下问题,

我已经实现了一个带有一些项目的Glance小部件,当你按下它们时,应用程序应该打开并导航到通过NavHost中的深度链接给出的特定屏幕。然而,有时页面导航通过深链接工作,有时不。如果不是,则出现如下错误:

Fatal signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x4d in tid 2486 (DefaultDispatch), pid 2259

我相信这是一个分割错误,因为我通过使用Gson()toJson(itemData)将参数从小部件传递到应用程序。然而,我不明白为什么这有时会起作用,因为我对每个项目使用相同的东西,以便打开应用程序并导航到详细信息屏幕。

另一件事是,当应用程序没有崩溃的错误,应用程序直接打开详细信息页面,而不是先显示开机画面导航到详细信息界面。

最后,我如何解决深度链接期间的分割错误,以及我如何预填充backstack(或只是先导航到splash,然后再到细节屏幕)?

关于更多信息,有一个示例代码:
// CODE IN GLANCE WIDGET
@Composable
private fun Item(
model: ItemData,
) {
val intent = Intent(
Intent.ACTION_VIEW,
"${URL}/${Screens.DetailScreen.passArgument(model.toDetailData())}".toUri() // pass model just converts detailData to string with Gson().toJson()
)
Text(
text = model.title ?: "",
modifier = GlanceModifier
.clickable(
actionStartActivity(
intent
)
)
)
}
// CODE IN NAVHOST
NavHost(
// navhost parameters such as route, controller, start destination
// where start destination set to Splash Screen
){
composable(/*routeOfSpashScreen*/){SplashScreen}
.
. // These dots are some sub-navGraphs
.
.
detailScreenNavGraph()
}
// DETAIL SCREEN SUB-NAVGRAPH
fun NavGraphBuilder.detailScreenNavGraph(
controller: NavHostController? = null // This is optional and does not relate to problem
) {
navigation(
startDestination = Screens.DetailScreen.route,
route = DETAIL_SCREEN_ROUTE
) {
composable(
route = Screens.DetailScreen.route + "/{model}",
arguments = listOf(
navArgument(
name = "model"
) {
type = DetailDataNavType()
},
),
deepLinks = listOf(
navDeepLink {
uriPattern = "${URL}/" + Screens.DetailScreen.route + "/{model}"
}
)
) {
val model = it.arguments?.getParcelable<DetailData>("model")
if (model != null) {
DetailScreen(
model,
controller = controller ?: LocalNavigationManager.current
)
}
}
}
}

任何帮助或建议都是感激的。

既然没有人回答,我已经解决了我的问题,我相信如果有人像我一样被困住了,我需要一个适当的解释。

  1. 什么是接收器,它们是如何工作的?

receiver就像单例类,它控制每个小部件,而不仅仅是被调用的小部件。如果你必须更新小部件,你应该有适当的GlanceId;目前,还没有官方的方法来获得这个id。但是,有一种很简单的方法,例如:

// Add this to your callback and to your intent before broadcasting it 
// so you can access the widget's GlanceId
val id = glanceId.toString().filter { it.isDigit() }.toInt()

既然你有你的接收器的onReceive的id,你可以正确地更新你的小部件

  1. 为什么出现"无法编组包含粘合剂对象的包裹";错误呢?

这是因为您正在使用LazyRow或LazyColumn和绘图期间,由于位图包含名为binder的智能组件,它在绘图期间占用内存中的额外空间,因此您超过了小部件内存的可用限制。我试着减小图像的大小,并尽可能地压缩它,但它加载了最恶心的图像。然而,如果你使用Column而不是LazyColumn,你可以很容易地渲染任何图像,至少这是我所经历的。

  1. 这些问题与我的问题有什么关系?

当我试图单击延迟加载的小部件上的一个项目时,我认为我试图访问在小部件绘制期间或之后已收集或释放的内存空间。另一种可能性是没有内存空间用于启动应用程序,在启动过程中,内存被清理,我试图访问已删除的内存部分。不管怎样,这些都只是假设,如果我错了,请随时纠正我。

  1. backstack部分怎么样?

我完全改变了应用程序的深度链接处理机制,如:

if(appIsClosed)
start splash -> navigate home -> open the desired page from here
// pass the received intent parameters throughout navigation hierarchy
else
handle as deep-link to home -> open desired page from here

最新更新