GitHub错误的项目:https://github.com/MediaPortal1/HowToDraw/blob/master/app/src/main/java/com/poltavets/app/
我的项目中有方法img.setImageResources(R.id.image),但是当我经常使用这种方法或更改屏幕方向时,它会调用OutOfmemory。 我发现这篇关于加载位图图像的文章“正确”:https://developer.android.com/training/displaying-bitmaps/load-bitmap.html 复制粘贴2本文的最后一个方法,并从以下位置更改我的代码:
imageView.setImageResource(image);
TO:
Handler handler=new Handler(){
@Override
public void handleMessage(Message msg) {
if(getRequestedOrientation()==ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE)
imageView.setImageBitmap(decodeSampledBitmapFromResource(getResources(), msg.what,100,100));
else imageView.setImageBitmap(decodeSampledBitmapFromResource(getResources(), msg.what,400,400));
}
};
handler.sendEmptyMessage(image);
我把这些方法放到Handler上,它的工作速度更快。并且我添加了方向条件,因为在陆地中,ImageView较小,而位图必须具有较小的分辨率。它工作正常,everithink还可以。但是我在这个项目中使用了另一个细节(只是将图像添加到我的项目中),并重新构建了这个项目2-3次,当我开始活动时再次出现OutOfMemory错误。在此错误出现之前并不总是如此,但现在它在我启动Activity时始终出现!怎么样?我不讨论这项活动的代码?我的图像真的很低。最大图像尺寸200kb。大小为100kb的图像如何调用OutOfMemory?
错误:
Process: com.poltavets.app.howtodraw, PID: 28720 java.lang.OutOfMemoryError: Failed to allocate a 35389452 byte allocation with 5482128 free bytes and 5MB until OOM
at dalvik.system.VMRuntime.newNonMovableArray(Native Method)
at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)
at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:655)
at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:488)
at android.graphics.BitmapFactory.decodeResource(BitmapFactory.java:511)
at com.poltavets.app.howtodraw.view.HowTo.decodeSampledBitmapFromResource(HowTo.java:224)
at com.poltavets.app.howtodraw.view.HowTo$3.handleMessage(HowTo.java:185)
at android.os.Handler.dispatchMessage(Handler.java:111)
at android.os.Looper.loop(Looper.java:194)
at android.app.ActivityThread.main(ActivityThread.java:5546)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:964)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:759)
ChangeImage代码(错误在这里):
public void changeImageSrc(int image,int count,int position,String name) {
filename=name+"_"+image+"_"+position;
imagenumber=position;
if(move!=null || back!=null) {
move.setEnabled(false);
back.setEnabled(false);
}
Handler handler=new Handler(){
@Override
public void handleMessage(Message msg) {
if(getRequestedOrientation()==ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE)
imageView.setImageBitmap(decodeSampledBitmapFromResource(getResources(), msg.what,100,100));
else imageView.setImageBitmap(decodeSampledBitmapFromResource(getResources(), msg.what,400,400)); // OUT OF MEMORY ERROR
}
};
handler.sendEmptyMessage(image);
getSupportActionBar().setTitle(getResources().getString(R.string.title_how_to) + " " + name + ": " + (position+1)+"/"+(count));
if(position==0 || position+1==count){
if(position==0){
findViewById(R.id.backBtn).setEnabled(false);
findViewById(R.id.backBtn).setVisibility(View.INVISIBLE);
}
else {
findViewById(R.id.moveBtn).setEnabled(false);
findViewById(R.id.moveBtn).setVisibility(View.INVISIBLE);
Toast.makeText(getApplicationContext(),getString(R.string.finish),Toast.LENGTH_SHORT).show();
}
}
else {
showNavButtons();
}
if(move!=null || back!=null) {
move.setEnabled(true);
back.setEnabled(true);
}
谷歌文章的两种方法:
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);
}
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;
}
答案 0 :(得分:0)
我什么也没做。我重新建造了这个项目3-4次,但没有帮助。但我现在只是重新构建它而没有任何变化,而且它有效。