我有一个应用程序,它对外部app进行多次异步调用,以获取有关图像缩略图的详细信息,以便在用户滚动时加载到我的RecyclerView中(使用幻灯片)。回收站是“永无止境的”,因为如果用户想要滚动足够长的时间,可以加载数千张图像。
在滚动了大概100张图片后,我得到了以下错误:
W/Adreno-GSL: <gsl_ldd_control:541>:ioctl fd 55 code 0xc0200933 (IOCTL_KGSL_TIMESTAMP_EVENT) failed: errno 24 Too many open files
<ioctl_kgsl_syncobj_create:3977>: (38, 1f, 3907) fail 24 Too many open files
E/Parcel: fcntl(F_DUPFD_CLOEXEC) failed in Parcel::read, i is 0, fds[i] is -1, fd_count is 1, error: Too many open files
I/Adreno: DequeueBuffer: dequeueBuffer failed
E/NativeCrypto: AppData::create pipe(2) failed: Too many open files
这个应用程序从来没有崩溃,但它仍然冻结,直到我(等一等?然后)退出应用程序,然后重新进入应用程序。
从我所做的研究中,我了解到一次可以打开多少文件是有限制的,但我不知道如何控制它。
发布于 2018-10-04 13:28:14
当屏幕上看不到项时,您应该取消api调用和其他异步工作。因为如果用户快速滚动,您将有数百个无用的任务正在运行。
因此,当视图被滚动时,只需取消您的任务。
您可以在RecylerView的void onViewRecycled (VH holder)
方法中完成所有这些工作。
来自文件:
void onViewRecycled (VH holder)
在此适配器创建的视图已被回收时调用。 当RecyclerView.LayoutManager决定不再需要附加到其父RecyclerView时,视图就会被回收。这可能是因为它失去了可见性,或者由仍然附加到父RecyclerView的视图表示的一组缓存视图。如果项目视图有大量或昂贵的数据绑定到它,如大位图,这可能是一个释放这些资源的好地方。 RecyclerView在清除ViewHolder的内部数据并将其发送到RecycledViewPool之前调用此方法。这样,如果ViewHolder在回收之前保存了有效信息,您可以调用getAdapterPosition()来获取它的适配器位置。
发布于 2018-10-04 12:59:43
我相信您所要做的就是在下载文件之后关闭连接/套接字:
Socket accept - "Too many open files"
如果您正在缓存下载的映像,则还应正确关闭FileInputStream
或FileOutputStream
。
此外,当根视图被销毁时,取消注册适配器:
@Override
protected void onDestroy() {
super.onDestroy();
recyclerView.setAdapter(null);
}
https://stackoverflow.com/questions/52654745
复制相似问题