使用自定义方法解码位图并将其设置为imageview作为背景。目前它工作正常,但在某些设备中,有时它会由于内存错误而崩溃。任何想法我如何操作代码并使其更好?这是我正在使用的:
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);
}
}
}
}
任何想法/建议/帮助都非常感谢!
答案 0 :(得分: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;
}
这将在您传递宽度和高度时缩放位图。
答案 1 :(得分:1)
在使用位图之后和分配另一个值之前使用bitmap.recycle()
。您还可以在实际使用之前缩小位图。这是一个链接:https://stackoverflow.com/a/13226982/1117338
另外一条建议:请在发布问题前仔细搜索。这是许多人已经解决的老问题。