理解Android位图图像中的缓存

时间:2014-02-24 21:22:57

标签: android performance memory-leaks surfaceview

您好我有这个代码,我试图通过谷歌开发者页面从Android示例中调整它。现在它被缓存但是当我进入缓存循环时,图像只显示在缓存中,而不在缓存中的图像无法显示任何想法如何解决这个问题?

由于我不熟悉编程和android API

,因此我可能缺少的东西很少
public class MainActivity extends Activity {

    ImageView animalView;
    Animal animal;
    private LruCache<String, Bitmap> mMemoryCache;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //setContentView(R.layout.activity_main);
        // RelativeLayout relativeLayout = (RelativeLayout)
        // findViewById(R.id.root);
        // surfaceView = new OurView(this);
        // relativeLayout.addView(surfaceView);



         // Get max available VM memory, exceeding this amount will throw an
        // OutOfMemory exception. Stored in kilobytes as LruCache takes an
        // int in its constructor.
        final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);

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

        mMemoryCache = new LruCache<String, Bitmap>(cacheSize) {
            @Override
            protected int sizeOf(String key, Bitmap bitmap) {
                // The cache size will be measured in kilobytes rather than
                // number of items.
                return bitmap.getByteCount() / 1024;
            }
        };

        setContentView(new Animal(this));

    }






    public class Animal extends SurfaceView implements
            SurfaceHolder.Callback, OnSharedPreferenceChangeListener {

        // private Bitmap bmp;
        private static final String KEY_COUNT = "count";;
        private Bitmap jeepbackbmp;
        private Bitmap jeepbmp;
        private Canvas canvas;
        private Bitmap scaled;
        private Bitmap background;
        private int clickCount = 0;
        final int[] AnimalsArray = { R.drawable.elephants,
                R.drawable.sable_antelope2560, R.drawable.wildebeest2560x1600,
                R.drawable.olive_babbon2560, R.drawable.plains_zebras2560,
                R.drawable.bush_pig2560, R.drawable.hippo_and_baby2560,
                R.drawable.african_buffalu2560, R.drawable.black_rhinos2560,
                R.drawable.giraffe_family2560, R.drawable.lessermaskedweaver,
                R.drawable.alcelaphus, R.drawable.cheetah };
        private SharedPreferences mPrefs;
        private int pX;
        private int pY;
        private Region jeepbackregion;
        private Region jeepgoregion;
        private SurfaceHolder mSurfaceHolder;
        private DisplayMetrics mDisplay;
        private Thread mDrawingThread;
        private int width;
        private int height;
        private float newWidth;
        private float newHeight;
        private int mDisplayWidth;
        private int mDisplayHeight;
        private Bitmap backgroundbmp;
        private ImageView mImageView;
        private Bitmap mBitmap;

        public Animal(Context context) {

            super(context);
            mPrefs = PreferenceManager
                    .getDefaultSharedPreferences(getContext());
            // If we are going to cache the name and gravity
            // Then we better find out when they are changed
            mPrefs.registerOnSharedPreferenceChangeListener(this);

            // mBitmapHeightAndWidthAdj = mBitmapHeightAndWidth / 2;



            BitmapFactory.Options options = new BitmapFactory.Options();
            options.inJustDecodeBounds = true;
            BitmapFactory.decodeResource(getResources(),
                    AnimalsArray[clickCount], options);

            mDisplay = new DisplayMetrics();
            MainActivity.this.getWindowManager().getDefaultDisplay()
                    .getMetrics(mDisplay);

            mDisplayWidth = mDisplay.widthPixels;
            mDisplayHeight = mDisplay.heightPixels;

            Display display = getWindowManager().getDefaultDisplay();
            Point size = new Point();
            display.getSize(size);
            width = size.x;
            height = size.y;


            background = decodeSampledBitmapFromResource(getResources(),AnimalsArray[clickCount], 160, 100);
            float Hscale = (float) background.getHeight() / height;
            float Wscale = (float) background.getWidth() / width;
            newWidth = background.getWidth() / Wscale;
            newHeight = background.getHeight() / Hscale;
            scaled = Bitmap.createScaledBitmap(background, (int) newWidth,
                    (int) newHeight, true);

            jeepbackbmp = BitmapFactory.decodeResource(getResources(),
                    R.drawable.jeep256right);
            jeepbmp = BitmapFactory.decodeResource(getResources(),
                    R.drawable.jeep256);

//          backgroundbmp = BitmapFactory.decodeResource(getResources(),
//                  R.id.imageView1);

            jeepbackregion = new Region(0, height - jeepbackbmp.getHeight(),
                    jeepbackbmp.getWidth(), height);

            jeepgoregion = new Region(width - jeepbmp.getWidth(), 0, width,
                    height);



//          RelativeLayout relativeLayout = (RelativeLayout) findViewById(R.id.frame);
//          animalView =  new ImageView(getApplicationContext());
//          animalView.setImageDrawable(getResources().getDrawable(R.drawable.giraffe_family2560));
//          relativeLayout.addView(animalView);




            mSurfaceHolder = getHolder();
            // mSurfaceHolder.setFixedSize(mBitmapHeightAndWidth, height);
            mSurfaceHolder.addCallback(this);

        }

        // ***************************************
        // ************* TOUCH *****************
        // ***************************************
        @Override
        public synchronized boolean onTouchEvent(MotionEvent ev) {

            pX = (int) ev.getX();
            pY = (int) ev.getY();

            switch (ev.getAction()) {

            case MotionEvent.ACTION_DOWN: {

                if (jeepbackregion.contains(pX, pY)) {

                    Log.d("AnimalView", "Back Touch Reached");
                    // jeepBack();
                }

                if (jeepgoregion.contains(pX, pY)) {
                    Log.d("AnimalView", "Go Touch Reached");
                    jeepGo();
                }

                // ballFingerMove = true;
                break;
            }

            case MotionEvent.ACTION_MOVE: {
                pX = (int) ev.getX() - jeepbackbmp.getWidth() / 2;
                pY = (int) ev.getY() - jeepbackbmp.getHeight() / 2;

                break;
            }

            case MotionEvent.ACTION_UP:
                // ballFingerMove = false;
                // dY = 0;
                break;
            }
            return true;
        }

        // private void jeepBack() {
        //
        // // vb.vibrate(100);
        // // anim = AnimationUtils.makeOutAnimation(MainActivity.this,
        // // true);
        // // jeepbackview.startAnimation(anim);
        // clickCount = -1 + mPrefs.getInt("clicked", 0);
        // if (clickCount < 0) {
        // clickCount = AnimalsArray.length - 1;
        // }
        // mPrefs.edit().putInt("clicked", clickCount)
        // .putBoolean("user", true).commit();
        //
        // if (clickCount >= 0 && clickCount <= AnimalsArray.length - 1) {
        //
        // background = BitmapFactory.decodeResource(getResources(),
        // AnimalsArray[clickCount]);
        // float Hscale = (float) background.getHeight()
        // / height;
        // float Wscale = (float) background.getWidth()
        // / width ;
        // float newWidth = background.getWidth() / Wscale;
        // float newHeight = background.getHeight() / Hscale;
        //
        // scaled = null;
        //
        // scaled =
        // Bitmap.createScaledBitmap(BitmapFactory.decodeResource(getResources(),
        // AnimalsArray[clickCount]),
        // (int) newWidth, (int) newHeight, true);
        //
        // }
        // }

        private void jeepGo() {

            Log.d("AnimalView", "jeepGO()  Reached");

            clickCount = 1 + mPrefs.getInt("clicked", 0);

            if (clickCount >= AnimalsArray.length -1) {
                clickCount = 0;
            }

            mPrefs.edit().putInt("clicked", clickCount)
                    .putBoolean("user", true).commit();

            Log.d("AnimalView", "Allocating new Bitmap  Reached");
            Log.d("AnimalView", "clicks " + clickCount);

            canvas = mSurfaceHolder.lockCanvas();
            if (null != canvas) {
                //drawAnimal(canvas);
                addBitmapToMemoryCache(String.valueOf(AnimalsArray[clickCount]), mBitmap);
                loadBitmap(AnimalsArray[(clickCount + 1)], mImageView);
                mSurfaceHolder.unlockCanvasAndPost(canvas);
            }

        }

        public void drawAnimal(Canvas canvas) {

            Bitmap b = decodeSampledBitmapFromResource(getResources(),AnimalsArray[clickCount], 160, 100);
            float Hscale = (float) b.getHeight() / height;
            float Wscale = (float) b.getWidth() / width;
            newWidth = b.getWidth() / Wscale;
            newHeight = b.getHeight() / Hscale;
            mBitmap = Bitmap.createScaledBitmap(BitmapFactory.decodeResource(
                    getResources(), AnimalsArray[clickCount]), (int) newWidth,
                    (int) newHeight, true);
            canvas.drawBitmap(mBitmap, 0, 0, null);
            canvas.drawBitmap(jeepbackbmp, 10,
                    getHeight() - jeepbackbmp.getHeight(), null);
            canvas.drawBitmap(jeepbmp, getWidth() - jeepbmp.getWidth(),
                    getHeight() - jeepbmp.getHeight(), null);

        }

        @Override
        public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2,
                int arg3) {
        }

        @Override
        public void surfaceCreated(SurfaceHolder holder) {
            mDrawingThread = new Thread(new Runnable() {
                public void run() {
                    Canvas canvas = null;
                    canvas = mSurfaceHolder.lockCanvas();
                    if (null != canvas) {
                        drawAnimal(canvas);
                        mSurfaceHolder.unlockCanvasAndPost(canvas);
                    }
                }
            });
            mDrawingThread.start();
        }

        @Override
        public void surfaceDestroyed(SurfaceHolder holder) {
            if (null != mDrawingThread)
                mDrawingThread.interrupt();
        }

        @Override
        public void onSharedPreferenceChanged(SharedPreferences arg0,
                String arg1) {
            // TODO Auto-generated method stub

        }

        public void loadBitmap(int resId, ImageView imageView) {
            final String imageKey = String.valueOf(resId);

            final Bitmap bitmap = getBitmapFromMemCache(imageKey);
            if (bitmap != null) {
                // setImageBitmap(bitmap);
                //mBitmap = decodeSampledBitmapFromResource(getResources(),AnimalsArray[clickCount], 160, 100);

                BitmapFactory.Options options = new BitmapFactory.Options();
                options.inPurgeable = true;
                Bitmap.createScaledBitmap(bitmap, width, height, true);



            } else {
               // mImageView.setImageDrawable(getResources().getDrawable(R.drawable.african_buffalu2560));
               //canvas.drawBitmap(scaled, 0, 0, null);
                drawAnimal(canvas);

                BitmapWorkerTask task = new BitmapWorkerTask(mImageView);
                task.execute(resId);
            }
        }

   }

    public static int calculateInSampleSize(BitmapFactory.Options options,
            int reqWidth, int reqHeight) {
        // Raw height and width of image
        final int height = options.outHeight;
        final int width = options.outWidth;
        int inSampleSize = 1;

        if (height > reqHeight || width > reqWidth) {

            final int halfHeight = height / 2;
            final int halfWidth = width / 2;

            // Calculate the largest inSampleSize value that is a power of 2 and
            // keeps both
            // height and width larger than the requested height and width.
            while ((halfHeight / inSampleSize) > reqHeight
                    && (halfWidth / inSampleSize) > reqWidth) {
                inSampleSize *= 2;
            }
        }

        return inSampleSize;
    }

    public static Bitmap decodeSampledBitmapFromResource(Resources res,
            int resId, int reqWidth, int reqHeight) {

        // First decode with inJustDecodeBounds=true to check dimensions
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeResource(res, resId, options);

        // Calculate inSampleSize
        options.inSampleSize = calculateInSampleSize(options, reqWidth,
                reqHeight);

        // Decode bitmap with inSampleSize set
        options.inJustDecodeBounds = false;

        return BitmapFactory.decodeResource(res, resId, options);
    }


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

        public BitmapWorkerTask(ImageView mImageView) {
            // TODO Auto-generated constructor stub
        }

        // Decode image in background.
        @Override
        protected Bitmap doInBackground(Integer... params) {
            final Bitmap bitmap = decodeSampledBitmapFromResource(
                    getResources(), params[0], 160, 100);
            addBitmapToMemoryCache(String.valueOf(params[0]), bitmap);
            return bitmap;
        }



    }

    public void addBitmapToMemoryCache(String key, Bitmap bitmap) {
        if (getBitmapFromMemCache(key) == null && bitmap != null) {
            mMemoryCache.put(key, bitmap);
            Log.d("AnimalView", "Bitmap added to cache" + key + bitmap);
        }
    }

    public Bitmap getBitmapFromMemCache(String key) {
          Log.d("AnimalView", "Get bitmap got as the key to" + key +  mMemoryCache.get(key) );
        return mMemoryCache.get(key);
    }
}

0 个答案:

没有答案