Почему ImageView.setImageURI () работает в Android 2.2, но не в 2.1?

Я показываю изображения и некоторый текст в виде списка с помощью адаптера. Изображения извлекаются из Интернета, затем кэшируются локально и отображаются. Изображения уже маленькие (квадрат 60 пикселей), и я знаю их размер, поэтому я использую совет , предлагающий использовать setImageURI вместо декодирования растрового изображения .

Класс, который выполняет эту работу, является модифицированной версией ImageLoader

Федора. Код прикрепляет заглушку, которую можно рисовать в ImageView, пока желаемое изображение не будет загружено из Интернета, а затем загружает кешированный файл с SD-карты. В Android 2.2 это прекрасно работает. Это быстро, и я не получаю сбоев OOM. Однако в версии 2.1 я получаю следующую ошибку:

09-15 11:04:52.993: INFO/System.out(240): resolveUri failed on bad bitmap uri: file:///sdcard/android/data/com.example.myapp/cache/4164137

Класс ImageLoader выглядит следующим образом:

/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements.  See the NOTICE file
distributed with this work for additional information
regarding copyright ownership.  The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License.  You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied.  See the License for the
specific language governing permissions and limitations
under the License.    
*/

public class ImageLoader {

    //the simplest in-memory cache implementation. This should be replaced with something like SoftReference or BitmapOptions.inPurgeable(since 1.6)
    private HashMap cache=new HashMap();

    private File cacheDir;

    public ImageLoader(Context context){
        //Make the background thead low priority. This way it will not affect the UI performance
        photoLoaderThread.setPriority(Thread.NORM_PRIORITY-1);

        //Find the dir to save cached images
        if (android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED))
            cacheDir=new File(android.os.Environment.getExternalStorageDirectory(),"Android/data/com.droidicon.launcherproicons/cache/");
        else
            cacheDir=context.getCacheDir();
        if(!cacheDir.exists())
            cacheDir.mkdirs();
    }

    final int stub_id=R.drawable.loading;
    public void DisplayImage(String url, Activity activity, ImageView imageView, int scaleSize)
    {
        if(cache.containsKey(url))
            imageView.setImageURI(cache.get(url));
        else
        {
            queuePhoto(url, activity, imageView, scaleSize);
            imageView.setImageResource(stub_id);
        }    
    }

    private void queuePhoto(String url, Activity activity, ImageView imageView, int scaleSize)
    {
        //This ImageView may be used for other images before. So there may be some old tasks in the queue. We need to discard them. 
        photosQueue.Clean(imageView);
        PhotoToLoad p=new PhotoToLoad(url, imageView, scaleSize);
        synchronized(photosQueue.photosToLoad){
            photosQueue.photosToLoad.push(p);
            photosQueue.photosToLoad.notifyAll();
        }

        //start thread if it's not started yet
        if(photoLoaderThread.getState()==Thread.State.NEW)
            photoLoaderThread.start();
    }
    private Uri getUri(String url, int scaleSize){
        if(url != ""){
            //I identify images by hashcode. Not a perfect solution, good for the demo.
//          try{
            String filename=String.valueOf(url.hashCode());
            File f=new File(cacheDir, filename);

            //from SD cache

            if(f.exists()){
                Uri b = Uri.fromFile(f);
                System.out.println(f.toString());
                return b;
            }

            //from web
            try {
                Uri bitmap=null;
                InputStream is=new URL(url).openStream();
                OutputStream os = new FileOutputStream(f);
                Utils.CopyStream(is, os);
                os.close();
                bitmap = Uri.fromFile(f);
                System.out.println(f.toString());
                return bitmap;
            } catch (Exception ex){
               ex.printStackTrace();
               return null;
            }
            } else {
                return null;
            }
    }


    //Task for the queue
    private class PhotoToLoad
    {
        public String url;
        public ImageView imageView;
        public int scaleSize;
        public PhotoToLoad(String u, ImageView i, int ss){
            url=u; 
            imageView=i;
            scaleSize=ss;
        }
    }

    PhotosQueue photosQueue=new PhotosQueue();

    public void stopThread()
    {
        photoLoaderThread.interrupt();
    }

    //stores list of photos to download
    class PhotosQueue
    {
        private Stack photosToLoad=new Stack();

        //removes all instances of this ImageView
        public void Clean(ImageView image)
        {
            for(int j=0 ;j

Вот один из адаптеров, реализующих этот ImageLoader:

public class ColorAdapter extends ArrayAdapter {
    private Activity activity;
    private int resource;
    private String response;
    private Context context;
    public ImageLoader imageLoader;


    public ColorAdapter(Activity a, Context context, int resource, List items){
        super(context, resource, items);
        this.resource=resource;
        imageLoader=new ImageLoader(context);
        activity = a;

    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent){
        Color color =  getItem(position);
        String minflater = Context.LAYOUT_INFLATER_SERVICE;
        LayoutInflater inflater;
        inflater = (LayoutInflater)getContext().getSystemService(minflater);
        ViewHolder holder;
        if(convertView==null){
            convertView = inflater.inflate(R.layout.listcolors, parent, false);
            holder=new ViewHolder();
            holder.txtName=(TextView)convertView.findViewById(R.id.txtName);
            //holder.txtUser=(TextView)convertView.findViewById(R.id.txtUser);
            holder.imgColorImg=(ImageView)convertView.findViewById(R.id.imgColorImg);

            convertView.setTag(holder);

        }
        else
            holder=(ViewHolder)convertView.getTag();

        holder.txtName.setText(color.getName());
        //holder.txtUser.setText(dock.getUser());
        holder.imgColorImg.setTag(color.getIconURL());
        imageLoader.DisplayImage(color.getIconURL(), activity, holder.imgColorImg, 84);
        return convertView;


    }

    class ViewHolder{
        TextView txtName;
        //TextView txtUser;
        ImageView imgColorImg;
    }



}

6
задан Community 23 May 2017 в 12:33
поделиться