目前,我正在开发一个启动器应用程序。该应用程序必须将所有图标加载到内存中。在某些旧设备中,当我通过PackageManager
加载应用图标时,应用会崩溃。这就是为什么我目前在后台主题中onBindViewHolder(...)
RecyclerView
方法中加载图标的原因:
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
// ...
Thread t = new Thread(new Runnable() {
@Override
public void run() {
try {
handler.postAtFrontOfQueue(new Runnable() {
Drawable drawable = activity.getPackageManager().getApplicationIcon(app.name.toString());
@Override
public void run() {
viewHolder.appIconIv.setImageDrawable(drawable);
}
});
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
}
});
t.start();
// ...
}
但是,这里的问题是,即使在后台加载图标,RecyclerView
在滚动时也会停滞不前/滞后。另外,如果我滚动到底部,所有图标都会加载到内存中,导致应用程序在较旧的设备上崩溃(RAM较少)。此外,我不认为这是一个很好的解决方案,因为它必须为视图的每个绑定创建一个新线程。所以,我的问题是,是否可以知道用户是否已经停止滚动(然后只加载图标)。
除了主要问题之外,我提到的任何问题的任何帮助都是真的非常赞赏,我将非常感激。 [特别是所有那些性能/ RAM问题:(]
提前致谢。 :d
答案 0 :(得分:1)
首先,我会建议不要使用postAtFrontOfQueue,因为害怕推回其他东西。如果你把事情推到前面,就会有可能永远不会被执行的事件导致奇怪的行为。
在我正在开发的应用程序中,我正在等待用毕加索加载图像,直到用户使用当前实现完成滚动/投掷。
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
if (newState == RecyclerView.SCROLL_STATE_IDLE) {
mPicasso.resumeTag(FeedViewHolder.SEARCH_IMAGE_TAG);
}
}
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
if (Math.abs(dy) > SCROLL_THRESHOLD) {
mPicasso.pauseTag(FeedViewHolder.SEARCH_IMAGE_TAG);
} else {
mPicasso.resumeTag(FeedViewHolder.SEARCH_IMAGE_TAG);
}
}
});
您可以使用picasso加载可绘制资源并像这样设置标记
mPicasso.load(R.drawable.image_resource_name)
.fit()
.centerCrop()
.tag(SEARCH_IMAGE_TAG)
.into(imageView);
答案 1 :(得分:1)
来自博客:Image Loading with Picasso
Picasso.pauseTag()
RecyclerView.addOnScrollListener(new PicassoOnScrollListener(this));
Picasso.with(imageView.getContext()。getApplicationContext()) .load(URL) .TAG(PicassoOnScrollListener.TAG) .into(ImageView的);