0

我是 Android 开发的初学者。我想从 SD 卡中以小尺寸显示图像。由于大图像速度很慢,所以我需要使用 a LruCache,但它不起作用。我也在使用 SwipeView。是一个 FileExplorer 示例。

这是我的ListFragment

public class Windows extends ListFragment {

    private File currentDir = new File(Environment.getExternalStorageDirectory().getPath() + "/Pictures/pic/");
    private FileArrayAdapter adapter;
    int fragNum;

    private LruCache<String, Bitmap> mMemoryCache;

    static Windows init(int val) {
        Windows List = new Windows();

        Bundle args = new Bundle();
        args.putInt("val", val);
        List.setArguments(args);

        return List;
    }

    public class FileArrayAdapter extends ArrayAdapter<Albumb> {

        private Context c;
        private int id;
        private List<Albumb> items;


        public FileArrayAdapter(Context context, int textViewResourceId, List<Albumb> objects) {
            super(context, textViewResourceId, objects);
            c = context;
            id = textViewResourceId;
            items = objects;
        }

        public Albumb getItem(int i) {
            return items.get(i);
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            View v = convertView;
            if (v == null) {
                LayoutInflater vi = (LayoutInflater) c.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                v = vi.inflate(id, null);
            }

            final Albumb item = items.get(position);
            if (item != null) {
                TextView t1 = (TextView) v.findViewById(R.id.TextView01);
                TextView t2 = (TextView) v.findViewById(R.id.TextView02);
                TextView t3 = (TextView) v.findViewById(R.id.TextViewDate);

                ImageView imageCity = (ImageView) v.findViewById(R.id.fd_Icon1);

                String type = item.getImage();
                if (type.equalsIgnoreCase("directory_icon")) {
                    String uri = "drawable/" + item.getImage();
                    int imageResource = c.getResources().getIdentifier(uri, null, c.getPackageName());
                    Drawable image = c.getResources().getDrawable(imageResource);
                    imageCity.setImageDrawable(image);

                } else {
                    final String imageKey = item.getName();
                    final Bitmap bm = getBitmapFromMemCache(currentDir + imageKey);

                    if (bm == null) {
                        BitmapWorkerTask task = new BitmapWorkerTask(imageCity);
                        task.execute(imageKey);
                    }
                }

                if (t1 != null)
                    t1.setText(item.getName());
                if (t2 != null)
                    t2.setText(item.getData());
                if (t3 != null)
                    t3.setText(item.getDate());

            }

            return v;
        }

        public Bitmap decodeSampledBitmapFromUri(String path, int reqWidth, int reqHeight) {

            Bitmap bm = null;

            final BitmapFactory.Options options = new BitmapFactory.Options();
            options.inJustDecodeBounds = true;
            BitmapFactory.decodeFile(path, options);
            options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
            options.inJustDecodeBounds = false;

            bm = BitmapFactory.decodeFile(path, options);

            return bm;
        }

        public int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
            final int height = options.outHeight;
            final int width = options.outWidth;
            int inSampleSize = 1;

            if (height > reqHeight || width > reqWidth) {
                if (width > height) {
                    inSampleSize = Math.round((float) height / (float) reqHeight);
                } else {
                    inSampleSize = Math.round((float) width / (float) reqWidth);
                }
            }

            return inSampleSize;
        }

        class BitmapWorkerTask extends AsyncTask<String, Void, Bitmap> {

            private final WeakReference<ImageView> imageViewReference;

            public BitmapWorkerTask(ImageView imageView) {
                imageViewReference = new WeakReference<ImageView>(imageView);
            }

            @Override
            protected Bitmap doInBackground(String... params) {

                final Bitmap bitmap = decodeSampledBitmapFromUri(params[0], 80, 80);
                addBitmapToMemoryCache(params[0], bitmap);
                return bitmap;
            }

            @Override
            protected void onPostExecute(Bitmap bitmap) {
                if (imageViewReference != null && bitmap != null) {
                    final ImageView imageView = (ImageView) imageViewReference.get();
                    if (imageView != null) {
                        imageView.setImageBitmap(bitmap);
                    }
                }
            }
        }
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        fragNum = getArguments() != null ? getArguments().getInt("val") : 1;


    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View layoutView = inflater.inflate(R.layout.windows_frag,
                container, false);


        final int memClass
                = ((ActivityManager) layoutView.getContext().getSystemService(Context.ACTIVITY_SERVICE))
                .getMemoryClass();

        // Use 1/8th of the available memory for this memory cache.
        final int cacheSize = 1024 * 1024 * memClass / 8;


        mMemoryCache = new LruCache<String, Bitmap>(cacheSize) {

            @Override
            protected int sizeOf(String key, Bitmap bitmap) {
                // The cache size will be measured in bytes rather than number of items.
                return bitmap.getByteCount();
            }
        };


        fill(currentDir);

        return layoutView;
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);

    }

    private void fill(File f) {
        File[] dirs = f.listFiles();

        List<Albumb> dir = new ArrayList<Albumb>();
        List<Albumb> fls = new ArrayList<Albumb>();
        try {
            for (File ff : dirs) {
                String name = ff.getName();
                Date lastModDate = new Date(ff.lastModified());
                DateFormat formater = DateFormat.getDateTimeInstance();
                String date_modify = formater.format(lastModDate);
            /*
             * Note: Remove this
             * name.equalsIgnoreCase("Personal" if u
             * want to list all ur sd card file and folder
             */
                if (ff.isDirectory()) {

                    File[] fbuf = ff.listFiles();
                    int buf = 0;
                    if (fbuf != null) {
                        buf = fbuf.length;
                    } else
                        buf = 0;
                    String num_item = String.valueOf(buf);
                    if (buf == 0)
                        num_item = num_item + " item";
                    else
                        num_item = num_item + " items";

                    // String formated = lastModDate.toString();
                    dir.add(new Albumb(ff.getName(), num_item, date_modify, ff
                            .getAbsolutePath(), "directory_icon"));
                } else {
                /*
                 * Note: Remove this
                 * f.getName().equalsIgnoreCase("Personal"
                 * if u want to list all ur sd card file and folder
                 */

                    fls.add(new Albumb(ff.getName(), ff.length() / 1024 + " KByte",
                            date_modify, ff.getAbsolutePath(), "file_icon"));

                }
            }
        } catch (Exception e) {

        }
        Collections.sort(dir);
        Collections.sort(fls);
        dir.addAll(fls);
        if (!f.getName().equalsIgnoreCase(Environment.getExternalStorageDirectory().getName() + "/Pictures/pic"))
            dir.add(0, new Albumb("..", "Parent Directory", "", f.getParent(),
                    "directory_up"));
        adapter = new FileArrayAdapter(getActivity(), R.layout.file_view, dir);
        this.setListAdapter(adapter);
    }


    public void addBitmapToMemoryCache(String key, Bitmap bitmap) {
        if (getBitmapFromMemCache(key) == null) {
            mMemoryCache.put(key, bitmap);
        }
    }

    public Bitmap getBitmapFromMemCache(String key) {
        return (Bitmap) mMemoryCache.get(key);
    }

    @Override
    public void onListItemClick(ListView l, View v, int position, long id) {
        super.onListItemClick(l, v, position, id);
        Albumb o = adapter.getItem(position);
        if (o.getImage().equalsIgnoreCase("directory_icon")
                || o.getImage().equalsIgnoreCase("directory_up")) {
            currentDir = new File(o.getPath());
            fill(currentDir);
        }

    }
}

这是我的视图模型ArrayAdapter

public class Albumb implements Comparable<Albumb> {
    private String name;
    private String data;
    private String date;
    private String path;
    private String image;

    public Albumb(String name, String date, String dt, String path, String image) {
        this.name = name;
        this.data = date;
        this.path = path;
        this.image = image;

    }

    public String getName() {
        return name;
    }

    public String getData() {
        return data;
    }

    public String getDate() {
        return date;
    }

    public String getPath() {
        return path;
    }

    public String getImage() {
        return image;
    }

    public int compareTo(Albumb o) {
        if (this.name != null)
            return this.name.toLowerCase().compareTo(o.getName().toLowerCase());
        else
            throw new IllegalArgumentException();
    }
}

日志猫:

05-01 23:43:08.257: E/AndroidRuntime(12687): FATAL EXCEPTION: AsyncTask #4
05-01 23:43:08.257: E/AndroidRuntime(12687): java.lang.RuntimeException: An error occured while executing doInBackground()
05-01 23:43:08.257: E/AndroidRuntime(12687):    at android.os.AsyncTask$3.done(AsyncTask.java:299)
05-01 23:43:08.257: E/AndroidRuntime(12687):    at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
05-01 23:43:08.257: E/AndroidRuntime(12687):    at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
05-01 23:43:08.257: E/AndroidRuntime(12687):    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
05-01 23:43:08.257: E/AndroidRuntime(12687):    at java.util.concurrent.FutureTask.run(FutureTask.java:137)
05-01 23:43:08.257: E/AndroidRuntime(12687):    at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
05-01 23:43:08.257: E/AndroidRuntime(12687):    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
05-01 23:43:08.257: E/AndroidRuntime(12687):    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
05-01 23:43:08.257: E/AndroidRuntime(12687):    at java.lang.Thread.run(Thread.java:856)
05-01 23:43:08.257: E/AndroidRuntime(12687): Caused by: java.lang.NullPointerException: key == null || value == null
05-01 23:43:08.257: E/AndroidRuntime(12687):    at android.support.v4.util.LruCache.put(LruCache.java:117)
05-01 23:43:08.257: E/AndroidRuntime(12687):    at com.example.swipetab.Windows.addBitmapToMemoryCache(Windows.java:349)
05-01 23:43:08.257: E/AndroidRuntime(12687):    at com.example.swipetab.Windows$FileArrayAdapter$BitmapWorkerTask.doInBackground(Windows.java:216)
05-01 23:43:08.257: E/AndroidRuntime(12687):    at com.example.swipetab.Windows$FileArrayAdapter$BitmapWorkerTask.doInBackground(Windows.java:1)
05-01 23:43:08.257: E/AndroidRuntime(12687):    at android.os.AsyncTask$2.call(AsyncTask.java:287)
05-01 23:43:08.257: E/AndroidRuntime(12687):    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)

谢谢您的帮助。

4

1 回答 1

0

将项目放入 LruCache 时,键和值都必须非空。

public final V put(K key, V value) {
    if (key == null || value == null) {
        throw new NullPointerException("key == null || value == null");
    }
    ...

在某些情况下,很可能 decodeSampledBitmapFromUri() 返回 null。

于 2014-05-01T22:40:04.273 回答