1

カスタムメソッドを使用してビットマップをデコードし、背景としてイメージビューに設定します。今のところ問題なく動作していますが、一部のデバイスではメモリ不足エラーが原因でクラッシュすることがあります。そのコードを最適化して改善するにはどうすればよいですか? これが私が使用しているものです:

    class BitmapWorkerTask extends AsyncTask<String, Void, Bitmap> {
    private final WeakReference<ImageView> imageViewReference;
    private String data = null;

    public BitmapWorkerTask(ImageView imageView) {
        // Use a WeakReference to ensure the ImageView can be garbage collected
        imageViewReference = new WeakReference<ImageView>(imageView);
    }

    // Decode image in background.
    @Override
    protected Bitmap doInBackground(String... params) {
        data = params[0];

        if(data != null){
            File bufferFile = new File(data);
            Log.e("","data : "+data);
            FileInputStream fis = null;
            try {
                fis = new FileInputStream(bufferFile);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }

            Cipher cipher = null;
            try {
                cipher = Cipher.getInstance("AES/CBC/NoPadding");
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
            } catch (NoSuchPaddingException e) {
                e.printStackTrace();
            }
            int userId = RPCCommunicator.getUserId(Store.this);
            String secretSalt = RPCCommunicator.getSecretKey(userId);
            String iv = RPCCommunicator.getIv(secretSalt);
            SecretKeySpec keySpec = new SecretKeySpec(secretSalt.getBytes(), "AES");
            IvParameterSpec ivSpec = new IvParameterSpec(iv.getBytes());
            try {
                cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
            } catch (InvalidKeyException e) {
                e.printStackTrace();
            } catch (InvalidAlgorithmParameterException e) {
                e.printStackTrace();
            }
            CipherInputStream cis = new CipherInputStream(fis, cipher);

            BitmapFactory.Options o2 = new BitmapFactory.Options();
            //o2.inSampleSize=2;
            o2.inTempStorage = new byte[4*1024];

            int width = (int) RPCCommunicator.getPlaceHolderWidth(Store.this, 45);
            int height = (int) RPCCommunicator.getPlaceHolderHeight(Store.this, 25);

            Rect rect = new Rect();
            rect.inset(width, height);

            Bitmap finall = BitmapFactory.decodeStream(cis,rect,o2);
            if(finall != null){
                Bitmap bmp = Bitmap.createScaledBitmap(finall, width, height, true);
                return bmp;
            } else {
                return null;
            }
        }
        return null;
    }

    // Once complete, see if ImageView is still around and set bitmap.
    @Override
    protected void onPostExecute(Bitmap bitmap) {
        if (imageViewReference != null) {
            final ImageView imageView = imageViewReference.get();
            if(bitmap != null){
                if (imageView != null) {
                    Animation animation = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.fadein);
                    imageView.startAnimation(animation);
                    imageView.setImageBitmap(bitmap);
                }
            } else {
                int width = (int) RPCCommunicator.getPlaceHolderWidth(Store.this, 45);
                int height = (int) RPCCommunicator.getPlaceHolderHeight(Store.this, 25);

                RelativeLayout.LayoutParams param = new RelativeLayout.LayoutParams(width, height);
                param.addRule(RelativeLayout.ALIGN_PARENT_TOP, RelativeLayout.TRUE);
                param.rightMargin = 15;
                imageView.setBackgroundResource(R.drawable.placeholder);
                imageView.setLayoutParams(param);
            }
        }
    }
}

どんなアイデア/提案/助けも本当に感謝しています!

4

2 に答える 2

3

このコードを試してください

public static Bitmap decodeFile(File f,int WIDTH,int HIGHT){
        try {
            //Decode image size
            BitmapFactory.Options o = new BitmapFactory.Options();
            o.inJustDecodeBounds = true;
            BitmapFactory.decodeStream(new FileInputStream(f),null,o);

            //The new size we want to scale to
            final int REQUIRED_WIDTH=WIDTH;
            final int REQUIRED_HIGHT=HIGHT;
            //Find the correct scale value. It should be the power of 2.
            int scale=1;
            while(o.outWidth/scale/2>=REQUIRED_WIDTH && o.outHeight/scale/2>=REQUIRED_HIGHT)
                scale*=2;

            //Decode with inSampleSize
            BitmapFactory.Options o2 = new BitmapFactory.Options();
            o2.inSampleSize=scale;
            return BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
        }
            catch (FileNotFoundException e) {}
        return null;
    }

これにより、幅と高さを渡すとビットマップがスケーリングされます..

于 2012-11-05T13:57:58.387 に答える
1

ビットマップを使用bitmap.recycle()した後、別の値を割り当てる前に使用します。実際に使用する前に、ビットマップを縮小することもできます。リンクは次のとおりです。https://stackoverflow.com/a/13226982/1117338

また、1 つのアドバイス: 質問を投稿する前によく検索してください。これは、多くの人がすでに解決した古い問題です。

于 2012-11-05T13:53:17.647 に答える