Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/201.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android listview中的位图加载是平稳的,但缓存到SD会滞后于应用程序_Android_Listview_Bitmap - Fatal编程技术网

Android listview中的位图加载是平稳的,但缓存到SD会滞后于应用程序

Android listview中的位图加载是平稳的,但缓存到SD会滞后于应用程序,android,listview,bitmap,Android,Listview,Bitmap,让我先说我有一个不寻常的图片来源。我正在从mp3文件的ID3标签中获取需要加载的位图 每当我加载封面图片并将其保存到SD存储时,我都会收到lagg。奇怪的是,所有的加载和保存都发生在后台线程上,因此它不应该影响UI线程我一次只运行一个操作,但仍然滞后 一旦我将所有图像保存到磁盘上,我就用保存文件的所有路径名构建了一个数组,它会像黄油一样滚动,所有图像都会毫不延迟地加载。因此,问题显然是对SD的缓存,而这并没有发生在UI线程上。(我可能是错的,所以你们来这里)从文件中加载图像是使用通用图像加载器完

让我先说我有一个不寻常的图片来源。我正在从mp3文件的ID3标签中获取需要加载的位图

每当我加载封面图片并将其保存到SD存储时,我都会收到lagg。奇怪的是,所有的加载和保存都发生在后台线程上,因此它不应该影响UI线程我一次只运行一个操作,但仍然滞后

一旦我将所有图像保存到磁盘上,我就用保存文件的所有路径名构建了一个数组,它会像黄油一样滚动,所有图像都会毫不延迟地加载。因此,问题显然是对SD的缓存,而这并没有发生在UI线程上。(我可能是错的,所以你们来这里)从文件中加载图像是使用通用图像加载器完成的,顺便说一句,但这不会造成任何问题:)

下面是存储封面艺术的代码片段:

public ExecutorService executor = Executors.newFixedThreadPool(1);

//this is where I schedule tasks for all mp3 files to be executed using the threadpool, 
//it is interrupted as soon as the user interacts with the listview (which should not be
//nessecary as it is not running any code on the UI thread)

public void preloadImages(){
    for(int i = 0; i < items.length; i++){
        if(scrolling){
            return;
        }
        if(items[i].type.equalsIgnoreCase("music") && imagePathArray[i] == null){
            ImageRunnable imgr = new ImageRunnable(items[i].pathname, null, i);
            executor.execute(imgr);
        }
        if(scrolling){
            return;
        }
    }
}
public ExecutorService executor=Executors.newFixedThreadPool(1);
//在这里,我计划使用threadpool执行所有mp3文件的任务,
//一旦用户与listview交互,它就会中断(不应该是
//nessecary(因为它没有在UI线程上运行任何代码)
公共图像(){
对于(int i=0;i
自定义可运行

//the custom runnable used to call the getCover method on separate thread
private class ImageRunnable implements Runnable {
    private String url;
    private final WeakReference<ImageView> imageViewReference;
    private boolean running = true;
    private int position;

    public ImageRunnable(String path, ImageView img, int pos) {
        url = path;
        imageViewReference = new WeakReference<ImageView>(img);
        position = pos;
    }

    public void terminate() {
        running = false;
    }

    @Override
    public void run() {
        android.os.Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
        final String coverPath = getCover(url, position);
    }
}
//用于在单独线程上调用getCover方法的自定义runnable
私有类ImageRunnable实现Runnable{
私有字符串url;
私有最终WeakReference imageViewReference;
私有布尔运行=真;
私人职位;
公共IMAGERUNABLE(字符串路径、ImageView img、int pos){
url=路径;
imageViewReference=新的WeakReference(img);
位置=位置;
}
公共无效终止(){
运行=错误;
}
@凌驾
公开募捐{
android.os.Process.setThreadPriority(Process.THREAD\u PRIORITY\u BACKGROUND);
最终字符串coverPath=getCover(url,位置);
}
}
getcover方法

private String getCover(String filepath, boolean refresh, int pos){
    Log.d(LOG_TAG, "BEGIN function");
    File file = new File(filepath);
    Log.d(LOG_TAG, "File read");
    MusicMetadataSet meta = null;

    try {
        meta = new MyID3().read(file);
        Log.d(LOG_TAG, "id3 read");
    } catch (IOException e) {
        Log.d(LOG_TAG, "error reading id3 tag of file");
        return null;
    }
    if(meta != null) {
        try {
            MusicMetadata metasimple = (MusicMetadata) meta.getSimplified();
            Log.d(LOG_TAG, "simplified");
            int length = filepath.length();
            String albumname = filepath.substring(length-15, length-5).replaceAll("[^a-zA-Z0-9.-]", "_");
            String path = Environment.getExternalStorageDirectory().toString();
            OutputStream fOut = null;
            Log.d(LOG_TAG, "album string");
            File fileo = new File(path, "id3tag/"+albumname+"_icon.jpg");
            Log.d(LOG_TAG, "file created");
            File dir = new File(path, "id3tag/");
            if(!dir.isDirectory()){
                dir.mkdirs();
            }
            if(!fileo.exists() || refresh){
                try {
                    fileo.createNewFile();
                    fOut = new FileOutputStream(fileo);

                    Vector<ImageData> fileList = metasimple.getPictureList();
                    Log.d(LOG_TAG, "got pic list");
                    ImageData data = fileList.lastElement();
                    if(fileList.size() == 0){
                        imagePathArray[pos] = "error";
                        return imagePathArray[pos];
                    }
                    byte[] rawimage = data.imageData;
                    Log.d(LOG_TAG, "got raw");
                    Bitmap bitmap = BitmapFactory.decodeByteArray(rawimage, 0, rawimage.length);
                    Log.d(LOG_TAG, "decoded bmp");
                    bitmap = bitmap.createScaledBitmap(bitmap, 64, 64, false);
                    Log.d(LOG_TAG, "scaled bmp");
                    bitmap.compress(Bitmap.CompressFormat.PNG, 100, fOut);
                    Log.d(LOG_TAG, "compr bmp");
                    fOut.flush();
                    fOut.close();
                    bitmap.recycle();
                    Log.d(LOG_TAG, "recycled");

                    meta = null;
                    rawimage = null;
                    fileList = null;
                    options = null;
                    metasimple = null;
                    bitmap = null;
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            imagePathArray[pos] = Uri.decode(fileo.toURI().toString().replace("file:/", "file:///"));
            return imagePathArray[pos];
        }catch (NoSuchElementException e){
            return null;
        }
    }
    return null;
}
private String getCover(字符串文件路径、布尔刷新、int-pos){
Log.d(Log_标签,“开始函数”);
文件文件=新文件(文件路径);
Log.d(Log_标签,“文件读取”);
MusicMetadataSet meta=null;
试一试{
meta=new MyID3().read(文件);
Log.d(Log_标签,“id3读取”);
}捕获(IOE异常){
Log.d(Log_标记,“读取文件的id3标记时出错”);
返回null;
}
if(meta!=null){
试一试{
MusicMetadata metasimple=(MusicMetadata)meta.getSimplified();
Log.d(Log_标签,“简化”);
int length=filepath.length();
字符串albumname=filepath.substring(长度-15,长度-5).replaceAll(“^a-zA-Z0-9.-”,“”);
字符串路径=Environment.getExternalStorageDirectory().toString();
OutputStream fOut=null;
Log.d(Log_标签,“唱片串”);
File fileo=新文件(路径“id3tag/”+albumname+“_icon.jpg”);
Log.d(Log_标记,“文件已创建”);
File dir=新文件(路径“id3tag/”);
如果(!dir.isDirectory()){
dir.mkdirs();
}
如果(!fileo.exists()| | refresh){
试一试{
fileo.createNewFile();
fOut=新文件输出流(fileo);
Vector fileList=metasimple.getPictureList();
Log.d(Log_标签,“got pic list”);
ImageData数据=fileList.lastElement();
if(fileList.size()==0){
imagePathArray[pos]=“错误”;
返回imagePathArray[pos];
}
字节[]rawimage=data.imageData;
Log.d(Log_标签,“got raw”);
位图位图=位图工厂.decodeByteArray(rawimage,0,rawimage.length);
Log.d(Log_标签,“解码bmp”);
位图=位图.createScaledBitmap(位图,64,64,false);
Log.d(Log_标签,“缩放bmp”);
compress(bitmap.CompressFormat.PNG,100,fOut);
Log.d(Log_标签,“compr bmp”);
fOut.flush();
fOut.close();
bitmap.recycle();
Log.d(Log_标签,“回收”);
meta=null;
rawimage=null;
fileList=null;
选项=空;
metasimple=null;
位图=空;
}catch(filenotfounde异常){
e、 printStackTrace();
}捕获(IOE异常){
e、 printStackTrace();
}
}
imagePathArray[pos]=Uri.decode(fileo.tori().toString().replace(“文件:/”,“文件:/”));
返回imagePathArray[pos];
}捕获(无接触元素例外e){
返回null;
}
}
返回null;
}

我现在也在处理同样的问题

对我来说,它似乎是多个GC调用,暂停所有线程,包括UI线程,以便找到可以释放的资源


检查您的LogCat消息以确认,查找带有标签的条目
dalvikm

尝试最小化新位图的分配。首先,您可以制作一个64x64位图并在其中绘制,而不是使用CreateScaledBitmap

其次,您可以通过BitmapFactory将位图传递给decodeByteArray来重用位图进行解码。选项

确定我找到了