Транзакция Слишком Большое исключение с rememberLauncherForActivityResult

#android #android-jetpack-compose

Вопрос:

У меня есть экран, на котором отображается LazyVerticalGrid с изображениями и верхняя панель с OnClick, которая создает новое действие для результата, чтобы выбрать каталог для отображения изображений

 @ExperimentalFoundationApi @Composable fun DisplayPictures(  pictures: Listlt;Urigt;,  navController: NavController,  appBarName: String = stringResource(id = R.string.choose_folder),  onNewDirectoryUri: (uri: Uri?) -gt; Unit = { } ) {  var showDirectorySelect by remember { mutableStateOf(false) }  if (showDirectorySelect) {  val launcher = rememberLauncherForActivityResult(  ActivityResultContracts.OpenDocumentTree(),  onResult = {  onNewDirectoryUri(it)  showDirectorySelect = false  })  LaunchedEffect(key1 = Unit) {  launcher.launch(null)  }  }  Scaffold(topBar = {  TopAppBar(title = {  Text(  text = appBarName.dropLastWhile { predicate -gt; predicate == '%' },  Modifier.padding(8.dp)  )  }, Modifier.clickable { showDirectorySelect = true })  })  {  if (!showDirectorySelect) {  LazyVerticalGrid(  maxColumnWidth = 150.dp,  paddingDp = 4.dp,  pictures = pictures  ) { uri -gt;  val route = Screen.Detail.createRoute(  URLEncoder.encode(  uri.toString(),  "UTF-8"  )  )  //Prevent multi-clicking and multi-touch  if (!navController.currentDestination?.route?.contains("detail")!!) {  navController.navigate(route)  }  }  }  } }  

Но по какой-то причине мое приложение вылетает с исключением TransactionTooLargeException после того, как пользователь выбрал каталог или просто закрыл приложение в фоновом режиме(например, нажал кнопку «Домой»). Я предполагаю, что проблема в LazyVerticalGrid(его еще одна составная функция, которая представляет собой просто ленивый столбец со строками), который содержит изображения. Таким образом, изображение является составной функцией, которая загружает изображение из URI

 //A wrapper around Image that shows placeholder and loading image via URI @ExperimentalFoundationApi @Composable fun Picture(  uri: Uri,  modifier: Modifier,  size: Size,  onClick: () -gt; Unit = {}, ) {  val bitmap: MutableStatelt;Bitmap?gt; = rememberSaveable { mutableStateOf(null) }  //Coil and other libraries that can get image from uri get context this way  val context = LocalContext.current  bitmap.value ?: run {  LaunchedEffect(Unit) {  launch(Dispatchers.IO) {  try {  bitmap.value = context.contentResolver.loadThumbnail(uri, size, null)  } catch (e: Exception) {  }  }  }  }  Box(  modifier = modifier  .aspectRatio(1f)  .placeholder(visible = bitmap.value == null)   ) {  bitmap.value?.let {  Log.i("longgg",uri.toString())  Image(  bitmap = it.asImageBitmap(),  contentDescription = null,  contentScale = ContentScale.Crop,  modifier = Modifier  .clip(RectangleShape)  .fillMaxSize()  .clickable { onClick() }  )  }  }  

По мере того, как я исследовал всю функцию создания, DisplayPictures перекомпозирует и LazyGrid загружает все изображения снова после завершения ActivityResultContract. Это приводит к загрузке большого количества миниатюр, и я получаю исключение TransactionTooLargeException. onNewDirectoryUri создает новое событие mvi, которое запускает изображения, но с новыми параметрами(новые изображения и т. Д.). Как я могу исправить это поведение?

Я узнал, что метод loadThumbnail создает пакет под капотом

 final Bundle opts = new Bundle(); opts.putParcelable(EXTRA_SIZE, new Point(size.getWidth(), size.getHeight()));  

Ответ №1:

Исключение TransactionTooLargeException возникает, когда данные, передаваемые между двумя действиями, слишком велики, я думаю, что пакет имеет ограничения на объем данных, которые он может переносить. Проверьте, какой результат вы отправляете через пакеты.

Старайтесь избегать отправки растровых изображений, вместо этого просто отправьте URL-адрес изображения и перезагрузите его в своей активности.

Комментарии:

1. Единственное, что я передаю через пакет, — это URI выбранного пользователем каталога. Я передаю только URI изображению, оно получает миниатюру(растровое изображение) внутри функции

2. Затем проверьте, сколько раз этот выбор Uri прерывается, если он прерывается в 3-4 Uri, то, безусловно, в пакете есть некоторые данные, которые вызывают этот сбой.