我正在尝试编写一种最快扫描整个SD卡的算法。我试图实现的是与QuickPic一致的东西,它具有SD卡的“正常速度”初始扫描,但任何后续刷新都非常快。
我已经尝试了几件事,而且我还有一些我没有测试的想法
1)始终扫描进入SD卡。我尝试过这个......初始扫描速度有点慢。但所有后续扫描都比较快,但速度不如QucikPic。
2)初始扫描后,将FileObserver添加到所有文件夹。虽然它只会增加大约1 MB的应用程序内存,但我担心这会影响性能甚至耗尽电池,因为它必须一直运行。此外,我在SD卡上有数据库,我不断获取创建/删除日志文件的事件。我确信在与其他应用程序合作时,会有其他文件夹/文件,我会不断收到通知。不确定性能是否正常。
3)使用MediaStore的数据。不幸的是,似乎我的HTC Desire Media商店并不总是与SD卡上的内容保持同步(不确定原因),但这还不够好。
3)使用ContentObserver。还没有尝试过这个,并且必须检查文档,但我感觉如果MediaStore的数据库中没有图像,那么我也不会从ContentObserver获取它。
你们有其他建议吗?基本上我需要的是在某些时候了解SD卡上的所有图像文件。初始扫描可能需要更长的时间,后续扫描应该尽可能快(我知道这取决于SD卡上的文件夹/文件的数量)但QuickPic扫描(或不管它做什么)整个SD卡大约0.6-0.8秒,而且我不能那么快。
答案 0 :(得分:0)
QuickPic 等真正的应用程序无疑使用 MediaStore 作为其来源。这是一个在 MediaStore 中查找所有外部图像文件及其缩略图的示例。
请注意,MediaStore 中的 DATA 列是指文件的完整路径。
import android.content.ContentResolver;
import android.content.Context;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.provider.MediaStore;
import androidx.loader.content.CursorLoader;
import java.io.IOException;
import java.util.ArrayList;
class ImageFileInfo
{
ImageFileInfo(String fileFullPath, Bitmap image, Bitmap thumbnail)
{
this.fileFullPath = fileFullPath;
this.image = image;
this.thumbnail = thumbnail;
}
String fileFullPath;
Bitmap image;
Bitmap thumbnail;
}
public class GetImageInfos
{
static ArrayList<ImageFileInfo> getImageInfos(Context context)
{
ArrayList<ImageFileInfo> list = new ArrayList<>();
final String[] cols = {
MediaStore.Images.Media._ID,
MediaStore.Images.Media.DATA };
CursorLoader loader = new CursorLoader(context);
loader.setUri(MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
loader.setProjection(cols);
loader.setSelection(null);
loader.setSortOrder(MediaStore.Images.Media.DATA);
Cursor cursor = loader.loadInBackground();
ContentResolver resolver = context.getContentResolver();
for (int i = 0; i < cursor.getCount(); i++)
{
cursor.moveToPosition(i);
int imagePathCol = cursor.getColumnIndex(MediaStore.Images.Media.DATA);
String imagePath = cursor.getString(imagePathCol);
int imageIdCol = cursor.getColumnIndex(MediaStore.Images.Media._ID);
int imageId = cursor.getInt(imageIdCol);
Bitmap image = BitmapFactory.decodeFile(imagePath);
Bitmap thumb = MediaStore.Images.Thumbnails.getThumbnail(
resolver, imageId, MediaStore.Images.Thumbnails.MINI_KIND, null);
list.add(new ImageFileInfo(imagePath, image, thumb));
}
return list;
}
}