在文件浏览器应用程序中加载缓慢的文件
Slow files loading in file browser app
我正在做一个android文件浏览器项目,其中TabLayout下会有四个片段。四个片段分别用于图像、视频、音频和文档。加载文件后,显示在相关的片段回收视图中。就像图像文件被加载到图像片段(选项卡)的回收视图中一样。
代码:
private class loader extends AsyncTask<Void,Void,Void> {
private Context ctx;
private loader(Context ctx){
this.ctx=ctx;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
progress.setMessage("Loading..");
progress.setProgressStyle(ProgressDialog.STYLE_SPINNER);
progress.setIndeterminate(true);
progress.show();
}
@Override
protected Void doInBackground(Void... params) {
getfile(root);
return null;
}
@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
try{
if(progress!=null&&progress.isShowing()){
//progress.cancel();
progress.dismiss();
}} catch (final IllegalArgumentException e) {
} catch (final Exception e) {
} finally {
progress = null;
}
pager.setAdapter(adapter);
tabLayout.setupWithViewPager(pager);
}
}
private void getfile(File dir) {
File listFile[] = dir.listFiles();
if (listFile != null && listFile.length > 0) {
for (int i = 0; i < listFile.length; i++) {
if (listFile[i].isDirectory()) {
// fileList.add(listFile[i]);
getfile(listFile[i]);
} else {
if (listFile[i].getName().endsWith(".jpg")||listFile[i].getName().endsWith(".png")||listFile[i].getName().endsWith(".jpeg"))
{
imageset.add(listFile[i].toString());
}
if (listFile[i].getName().endsWith(".mp4")||listFile[i].getName().endsWith(".avi")||listFile[i].getName().endsWith(".3gp"))
{
videoset.add(listFile[i].toString());
}
if (listFile[i].getName().endsWith(".mp3"))
{
audioset.add(listFile[i].toString());
}
if (listFile[i].getName().endsWith(".pdf")
|| listFile[i].getName().endsWith(".doc")
|| listFile[i].getName().endsWith(".docx")
|| listFile[i].getName().endsWith(".txt"))
{
fileset.add(listFile[i].toString());
}
}
}
}
}
代码运行良好。但加载文件的性能在少数设备中较慢,而在少数设备中速度较快。每次 activity 启动它加载,每当屏幕旋转它加载。我不希望它在每次 activity 启动时加载。我想把文件放在数据库中,这样我就可以快速加载文件。但是每当添加新文件时,数据库都无法自动更新。那么实现这一目标的最佳方法是什么?
更新:
private void getFile(File dir) {
File[] listFile = dir.listFiles(new FilenameFilter() {
@Override
public boolean accept(File dir, String filename) {
Log.d("FILENAME", filename);
if (dir.isDirectory()) {
getFile(dir);
return false;
}
String name = dir.getName();
if (name.endsWith(".jpg") || name.endsWith(".png") || name.endsWith(".jpeg"))
{
imageset.add(name);
}
if (name.endsWith(".3gp") || name.endsWith(".avi") || name.endsWith(".mp4"))
{
videoset.add(name);
}
if (name.endsWith(".mp3"))
{
audioset.add(name);
}
if (name.endsWith(".txt") || name.endsWith(".doc") || name.endsWith(".docx")||name.endsWith(".pdf"))
{
fileset.add(name);
}
return false;
}
});
for(File f : listFile){ System.out.println(f.getName()); }
}
您的代码在多个方面效率很低:
您没有使用局部变量。调用 listFile[i]
和 listFile[i].getName()
几十次是非常低效的。
你是检索完整的文件然后过滤,而不是在检索的时候直接过滤。您可以通过实施 FileFilter 来做到这一点。我们不使用 listFiles 的 return 值,因此 accept() 方法仅 returns false.
dir.listFiles(new FileFilter() {
@Override
public boolean accept(File pathname) {
if (pathname.isDirectory()) {
getfile(pathname);
return false;
}
String name = pathname.getName();
if (name.endsWith(".jpg") || name.endsWith(".png") || name.endsWith(".jpeg") || name.endsWith(".mp4")
|| name.endsWith(".avi") || name.endsWith(".3gp") || ...) {
fileset.add(pathname);
}
return false;
}
});
我正在做一个android文件浏览器项目,其中TabLayout下会有四个片段。四个片段分别用于图像、视频、音频和文档。加载文件后,显示在相关的片段回收视图中。就像图像文件被加载到图像片段(选项卡)的回收视图中一样。
代码:
private class loader extends AsyncTask<Void,Void,Void> {
private Context ctx;
private loader(Context ctx){
this.ctx=ctx;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
progress.setMessage("Loading..");
progress.setProgressStyle(ProgressDialog.STYLE_SPINNER);
progress.setIndeterminate(true);
progress.show();
}
@Override
protected Void doInBackground(Void... params) {
getfile(root);
return null;
}
@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
try{
if(progress!=null&&progress.isShowing()){
//progress.cancel();
progress.dismiss();
}} catch (final IllegalArgumentException e) {
} catch (final Exception e) {
} finally {
progress = null;
}
pager.setAdapter(adapter);
tabLayout.setupWithViewPager(pager);
}
}
private void getfile(File dir) {
File listFile[] = dir.listFiles();
if (listFile != null && listFile.length > 0) {
for (int i = 0; i < listFile.length; i++) {
if (listFile[i].isDirectory()) {
// fileList.add(listFile[i]);
getfile(listFile[i]);
} else {
if (listFile[i].getName().endsWith(".jpg")||listFile[i].getName().endsWith(".png")||listFile[i].getName().endsWith(".jpeg"))
{
imageset.add(listFile[i].toString());
}
if (listFile[i].getName().endsWith(".mp4")||listFile[i].getName().endsWith(".avi")||listFile[i].getName().endsWith(".3gp"))
{
videoset.add(listFile[i].toString());
}
if (listFile[i].getName().endsWith(".mp3"))
{
audioset.add(listFile[i].toString());
}
if (listFile[i].getName().endsWith(".pdf")
|| listFile[i].getName().endsWith(".doc")
|| listFile[i].getName().endsWith(".docx")
|| listFile[i].getName().endsWith(".txt"))
{
fileset.add(listFile[i].toString());
}
}
}
}
}
代码运行良好。但加载文件的性能在少数设备中较慢,而在少数设备中速度较快。每次 activity 启动它加载,每当屏幕旋转它加载。我不希望它在每次 activity 启动时加载。我想把文件放在数据库中,这样我就可以快速加载文件。但是每当添加新文件时,数据库都无法自动更新。那么实现这一目标的最佳方法是什么?
更新:
private void getFile(File dir) {
File[] listFile = dir.listFiles(new FilenameFilter() {
@Override
public boolean accept(File dir, String filename) {
Log.d("FILENAME", filename);
if (dir.isDirectory()) {
getFile(dir);
return false;
}
String name = dir.getName();
if (name.endsWith(".jpg") || name.endsWith(".png") || name.endsWith(".jpeg"))
{
imageset.add(name);
}
if (name.endsWith(".3gp") || name.endsWith(".avi") || name.endsWith(".mp4"))
{
videoset.add(name);
}
if (name.endsWith(".mp3"))
{
audioset.add(name);
}
if (name.endsWith(".txt") || name.endsWith(".doc") || name.endsWith(".docx")||name.endsWith(".pdf"))
{
fileset.add(name);
}
return false;
}
});
for(File f : listFile){ System.out.println(f.getName()); }
}
您的代码在多个方面效率很低:
您没有使用局部变量。调用
listFile[i]
和listFile[i].getName()
几十次是非常低效的。你是检索完整的文件然后过滤,而不是在检索的时候直接过滤。您可以通过实施 FileFilter 来做到这一点。我们不使用 listFiles 的 return 值,因此 accept() 方法仅 returns false.
dir.listFiles(new FileFilter() { @Override public boolean accept(File pathname) { if (pathname.isDirectory()) { getfile(pathname); return false; } String name = pathname.getName(); if (name.endsWith(".jpg") || name.endsWith(".png") || name.endsWith(".jpeg") || name.endsWith(".mp4") || name.endsWith(".avi") || name.endsWith(".3gp") || ...) { fileset.add(pathname); } return false; } });