gpt4 book ai didi

java - 高效加载媒体缩略图

转载 作者:行者123 更新时间:2023-11-30 01:12:41 30 4
gpt4 key购买 nike

我花了几天时间来解决这个问题,但仍然找不到解决方案。我是 Android 新手,所以我的代码可能很乱!

我有一个显示图像和视频缩略图的 RecyclerView(网格布局)。它加载特定文件夹中的媒体文件。但是当我启动这个 Activity 时,它占用了这么多内存!

为了加载缩略图,我创建了两个线程。

Thread 1) MediaLoadThread查询SDCard中的媒体文件。它通过游标和队列缩略图解码任务循环到不同的线程。

Thread 2) ThumbnailLoaderThread 解码每个单独的缩略图。它接收内容解析器、媒体类型(图像或视频)和媒体 ID。它使用基本的 .getThumbnail() 方法。完成获取缩略图后,它会触发对其调用者线程 (MediaLoadThread) 的响应回调。

3) 当 MediaLoadThread(Thread 1) 收到回调时,它会触发另一个回调,让 Activity 更新给定位置的适配器项。适配器更新 UI,最后缩略图 ImageView 从占位符更改为实际缩略图。

:::这是我的代码:::

1) MediaLoadThread.java

@Override
public void run() {
mMediaDataArr.clear();
mLoaderThread.start(); // Prepping the thread 2
mLoaderThread.prepareHandler();

// .... SD Card query stuff .....

if (mediaCursor != null && mediaCursor.moveToFirst()) {
do {
mMediaDataArr.add(new MediaData(videoCursor.getInt(columnIndexId),
mediaCursor.getLong(columnIndexDate), //ID
mediaCursor.getInt(columnIndexType), //MEDIA TYPE
null); //THUMBNAIL BITMAP (NULL UNTIL THE ACTUAL THUMBNAIL IS DECODED)
} while (mediaCursor.moveToNext());
mediaCursor.close();
mResponseHandler.post(new Runnable() {
@Override
public void run() {
// This callback lets the activity activate the adapter and recyclerview so that the user can interact with recyclerview before the app finishes decoding thumbnails.
mCallback.onVideoLoaded(mMediaDataArr);
}
});

//Passing tasks to thread 2
for (int i = 0; i < mMediaDataArr.size(); i++) {
mLoaderThread.queueTask(
mMediaDataArr.get(i).getmMediaType(),
i, mMediaDataArr.get(i).getmMediaId());
}
}
}
}

// This is triggered by thread 2 when it finishes decoding
@Override
public void onThumbnailLoaded(final int position, final Bitmap thumbnail) {
mResponseHandler.post(new Runnable() {
@Override
public void run() {
mCallback.onThumbnailPrepared(position, thumbnail);
}
});
}

2) ThumbnailLoaderThread.java

public void queueTask(int mediaType, int position, int videoId) {
mWorkerHandler.obtainMessage(mediaType, position, videoId).sendToTarget();
}

public void prepareHandler() {
mWorkerHandler = new Handler(getLooper(), new Handler.Callback() {
@Override
public boolean handleMessage(Message msg) {
int type = msg.what;
final int position = msg.arg1;
int videoId = msg.arg2;
try {
if (type == MediaStore.Files.FileColumns.MEDIA_TYPE_IMAGE) {
Bitmap newThumb = MediaStore.Images.Thumbnails
.getThumbnail(mCr, videoId,
MediaStore.Images.Thumbnails.MINI_KIND, null);
postResult(position, newThumb);

} else if (type == MediaStore.Files.FileColumns.MEDIA_TYPE_VIDEO) {
Bitmap newThumb = MediaStore.Video.Thumbnails
.getThumbnail(mCr, videoId,
MediaStore.Video.Thumbnails.MINI_KIND, null);
postResult(position, newThumb);
}
} catch (Exception e) {
e.printStackTrace();
}
return true;
}
});
}

private void postResult(final int position, final Bitmap newThumb) {
mResponseHandler.post(new Runnable() {
@Override
public void run() {
mCallback.onThumbnailLoaded(position, newThumb);
}
});
}

3) LibraryActivity.java

@Override
public void onThumbnailPrepared(int position, Bitmap thumbnail) {
if (thumbnail != null && position < mData.size()) {
MediaData updatedData = mData.get(position);
updatedData.setmThumbnail(thumbnail);
mData.set(position, updatedData);
mVideoAdapter.notifyItemChanged(position);
}
}

流程是这样的。

1) Activity 启动线程1。

2) 线程 1 开始查询文件并启动线程 2。它通过游标循环传递媒体 ID。

3) 线程 2 解码具有给定媒体 ID 的缩略图。

4) 解码完成后,线程 2 使用结果位图触发对线程 1 的回调。

5)线程1接收到位图,通过回调将位图传递给activity。

6) Activity 接收缩略图并使用给定的位图更新 RecyclerView 数据。

它工作正常,但是当系统为这个任务分配将近 50MB 的内存时......考虑到它只加载 100 个缩略图,我认为它很重。

:::我试过的:::

1) 我提取了每个单独缩略图的 URI,并让 recyclerview 适配器在绑定(bind)时加载具有给定 URI 的图像。它工作正常并且没有消耗那么多内存,但是因为它在绑定(bind)项目时加载图像,所以每当我稍微延迟滚动屏幕时它都会重新加载缩略图。

2) 我让适配器使用直接缩略图路径加载缩略图。但是当用户清理/.thumbnails 文件夹时,它将不起作用。

3) 当线程解码缩略图时,我将 BitmapFactory.Options samplsize 设置为 4。但是当它仍然很重甚至有时更慢时......

4) 在MediaData对象中,将缩略图位图保存为成员变量。所以我在适配器将它加载到 ImageView 后立即将其设置为 null。仍然很重,并且因为我将对象的缩略图设为空,所以当我向后滚动时它只显示占位符。

我真的不知道。任何帮助将不胜感激!!

最佳答案

您可以使用 nostra universal用于加载图像的图像加载器库。这个库非常适合图像加载,还有一些其他库,如 Picasso , glide等可用,您可以使用它们而不是进行手动编码。

关于java - 高效加载媒体缩略图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38266319/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com