I have a list with many items. These Items are shown with its image and to not having problems with memory I've done a 'infinite scrolling' which the streamBuilder loads 10 items, and when user gets the bottom it loads more 10. But if I load more than 20 items, the app freezes and crashes...
This is the method to get the items from Firebase:
Future<void> loadnovo(
{String submenu,
int limit = 10,
bool limpar = false,
bool carregamentoInicial = false,
int lastIndex}) async {
if (limpar) {
conteudo.clear();
hasMore = true;
}
_isLoading = true;
var parts = submenu.split('/');
var pathSlashless = parts[0].trim();
var subPathSlashless = parts.sublist(1).join('/').trim();
var snapshot = await _storage.ref().child("/${submenu}");
var retorno = await snapshot.listAll();
if (subPathSlashless.isEmpty || subPathSlashless == null) {
retorno.prefixes.forEach((element) {
conteudo.add(
ItemLab(
tipo: 'PASTA',
elemento: element,
),
);
_streamController.add(conteudo);
});
}
for (int i = lastIndex; i < lastIndex + limit; i++) {
var url = await retorno.items[i].getDownloadURL();
conteudo.add(
ItemLab(
tipo: 'FILE',
elemento: retorno.items[i],
imageUrl: url,
),
);
_streamController.add(conteudo);
}
hasMore = true;
if (subPathSlashless.isNotEmpty) {
List items;
await databaseReference
.collection("lab_${pathSlashless}_url")
.snapshots()
.forEach((element) {
element.docs.forEach((f) {
if (f.data()['videos'] != null) {
items == null
? items = f.data()['videos']
: items.addAll(f.data()['videos']);
}
;
});
});
for (int i = 0; i < items.length; i++) {
conteudo.add(
ItemLab(
tipo: 'VIDEO',
elemento: null,
video: items[i],
),
);
_streamController.add(conteudo);
}
} else {
await databaseReference
.collection("lab_${pathSlashless}_url")
.snapshots()
.forEach((element) {
element.docs.forEach((f) async {
if (f.data().isNotEmpty) {
if (f.data().keys.contains("videos")) {
conteudo.add(
ItemLab(
tipo: 'PASTA',
pastaVideo: findFolderName(f.reference.path)),
);
_streamController.add(conteudo);
} else {
conteudo.add(
ItemLab(
tipo: 'VIDEO',
elemento: null,
video: f.data(),
),
);
_streamController.add(conteudo);
}
}
});
});
}
pathSlashless = null;
subPathSlashless = null;
}
This is the list:
LabController ctrlLab;
final lab = LabMdScreen();
inal scrollController = ScrollController();
int lastIndex = 0;
scrollListener() async {
if (scrollController.position.maxScrollExtent == scrollController.offset) {
lastIndex += 10;
ctrlLab.loadList(submenu: "ph/Res", lastIndex: lastIndex);
}
}
@override
void initState() {
ctrlLab = LabController();
ctrlLab.loadList(submenu: "ph/Res", lastIndex: lastIndex,cls: true, initialLoad: true);
scrollController.addListener(scrollListener);
super.initState();
}
@override
void dispose() {
scrollController.removeListener(scrollListener);
super.dispose();
}
loadBasicStructureDetail(submenu ,callback, context, deviceSize){
return StreamBuilder(
stream: ctrlLab.stream,
builder: (ctx, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(child: CircularProgressIndicator());
} else if (snapshot.error != null) {
print(snapshot.error);
return Center(child: Text('Ocorreu um erro!'));
}else {
return GridView.builder(
padding: EdgeInsets.all(10.0),
controller: scrollController,
itemCount: snapshot.data.length +1,
itemBuilder: (ctx, i) {
path = callback;
if (i < snapshot.data.length) {
ItemLab item = snapshot.data[i];
return Dismissible(
key: UniqueKey(),
direction: DismissDirection.endToStart,
background: Container(
padding: EdgeInsets.all(10.0),
color: Colors.grey[800],
child: Align(
alignment: AlignmentDirectional.centerEnd,
child: Icon(
Icons.delete,
color: Colors.white,
size: 40,
),
),
),
onDismissed: (DismissDirection direction) {
},
child: GestureDetector(
child: Card(
elevation: 5.0,
child: Padding(
padding: EdgeInsets.all(10.0),
child: GridTile(
child: Hero(
tag: "${item}",
child: item.imageUrl == null
? setIconLab(item)
: CachedNetworkImage(
fit: BoxFit.cover,
imageUrl: setIconLab(item),
placeholder: (ctx, url) =>
Center(child: CircularProgressIndicator()),
errorWidget: (context, url, error) =>
Image.asset('assets/images/semfoto.jpg',
fit: BoxFit.cover),
),
),
footer: Container(
padding: EdgeInsets.all(8.0),
color: Colors.white70,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
item.elemento == null
? item.video['nome']
: item.elemento.name,
overflow: TextOverflow.ellipsis,
style: TextStyle(
color: Theme
.of(context)
.textTheme
.caption
.color,
),
),
],
),
),
),
),
),
onTap: () async {
String url = item.elemento == null ? await item
.video["url"] :
await item.elemento.getDownloadURL();
ctrlLab.openImage(url);
},
),
);
}else if (ctrlLab.hasMore) {
return Padding(
padding: EdgeInsets.symmetric(vertical: 32.0),
child: Center(child: CircularProgressIndicator()),
);
} else {
return SizedBox(
height: 30,
);
}
},
gridDelegate: SliverGridDelegateWithFixedCrossAxisCountAndLoading(
itemCount: snapshot.data.length +1,
crossAxisCount: deviceSize.width < 600 ? 2 : 3,
childAspectRatio: 0.7,
crossAxisSpacing: 10.0,
mainAxisSpacing: 10.0,
),
);
How to avoid this problem and be able to load all the items from that folder without memory problems
Error when closes the app:
W/Adreno-GSL(30159): <sharedmem_gpuobj_alloc:2021>: sharedmem_gpumem_alloc: mmap failed errno 12 Out of memory
E/Adreno-GSL(30159): <gsl_memory_alloc_pure:2125>: GSL MEM ERROR: kgsl_sharedmem_alloc ioctl failed.
F/libc (30159): Fatal signal 11 (SIGSEGV), code 1, fault addr 0x7ce5f818 in tid 30195 (1.raster)
*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
Build fingerprint: 'Lenovo/karate/K33a48:7.0/NRD90N/K33_S231_171114_ROW:user/release-keys'
Revision: '0'
ABI: 'arm'
pid: 30159, tid: 30195, name: 1.raster >>> com.example.app_md <<<
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x7ce5f818
r0 48e09801 r1 00000000 r2 00000000 r3 00000000
r4 7ce5f810 r5 00000000 r6 00000000 r7 00000000
r8 00000000 r9 7bb59700 sl 00000000 fp 00000000
ip 00000000 sp 88d84e08 lr 987fa495 pc 987fa554 cpsr 600f0030
backtrace:
#00 pc 001d9554 /system/vendor/lib/egl/libESXGLESv2_adreno.so (_ZN10A5xContext25HwPatchForDirectRenderingEP15EsxRenderBucketP13EsxLinkedListj+307)
#01 pc 000bf5cb /system/vendor/lib/egl/libESXGLESv2_adreno.so (_ZN10EsxContext23PatchForDirectRenderingEP15EsxRenderBucketP13EsxLinkedListj+10)
#02 pc 000c5031 /system/vendor/lib/egl/libESXGLESv2_adreno.so (_ZN10EsxContext25ProcessAndSubmitRenderingE14EsxFlushReason+1392)
#03 pc 00147553 /system/vendor/lib/egl/libESXGLESv2_adreno.so (_ZN9EsxCmdMgr5FlushE14EsxFlushReason+722)
#04 pc 000c29fd /system/vendor/lib/egl/libESXGLESv2_adreno.so (_ZN10EsxContext11SwapBuffersEPK7EsxRectj+92)
#05 pc 0012deab /system/vendor/lib/egl/libESXGLESv2_adreno.so (_ZN10EglContext11SwapBuffersEPK7EsxRectj+74)
#06 pc 001393af /system/vendor/lib/egl/libESXGLESv2_adreno.so (_ZN16EglWindowSurface27PerformContextSwapOperationEP10EglContextPK7EsxRectjP21EglResourceAccessInfo+46)
#07 pc 00139441 /system/vendor/lib/egl/libESXGLESv2_adreno.so (_ZN16EglWindowSurface11SwapBuffersEP10EglContextPK7EsxRectj+32)
#08 pc 0012a8af /system/vendor/lib/egl/libESXGLESv2_adreno.so (_ZN6EglApi11SwapBuffersEPvS0_+110)
#09 pc 0000d20f /system/lib/libEGL.so (eglSwapBuffersWithDamageKHR+290)
#10 pc 00000fdb /data/app/com.example.app_md-1/lib/arm/libflutter.so (offset 0x1002000)
Lost connection to device.