我正在编写一个需要大量内存的Android应用程序,并且遇到了内存不足的问题。该应用程序有两个活动。主要活动使用一系列按钮,这些按钮使用事件处理程序在第二个活动中将不同的图像加载到ImageViews中。当用户按下Android后退按钮时,应用程序将返回主活动。
我遇到的问题是,最终,应用程序因OutOfMemory错误而崩溃。
下图显示了我在应用程序的内存使用情况,因为我在两个活动之间来回切换。拍摄此屏幕截图后,我再次尝试通过其中一个按钮打开第二个活动,然后再次出现错误。 你会注意到最后一个驼峰远离其他驼峰。这是因为我停了一秒钟拍摄截图,期望下一次尝试会让它崩溃。如果我没有再次截图。
我认为可以通过显式强制活动在不使用时释放内存来解决问题。这个问题是我不知道如何做到这一点,并且无法在线找到任何明确的解释,详细说明如何做到这一点。
以下是“图像视图”活动的代码示例:
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Point;
import android.os.Bundle;
import android.os.Environment;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.widget.ImageView;
import android.widget.TableRow;
import java.io.File;
public class ViewPost extends AppCompatActivity {
Context appContext = this;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_view_image);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
}
@Override
protected void onResume() {
super.onResume();
new Thread(new Runnable() {
@Override
public void run() {
final ImageView imgPhoto = (ImageView) findViewById(R.id.imgPhoto);
final TableRow photoLayout = (TableRow) findViewById(R.id.photoLayout);
// Get the width of the device screen.
Point screenDimensionFinder = new Point();
getWindowManager().getDefaultDisplay().getSize(screenDimensionFinder);
final int screenWidth = screenDimensionFinder.x;
runOnUiThread(new Runnable() {
@Override
public void run() {
File imageFolder = new File(String.valueOf(appContext.getExternalFilesDir(
Environment.DIRECTORY_PICTURES)));
File photoFile = new File(imageFolder, "P" + Integer.toString(postId) +
".jpg");
if(photoFile.exists()) {
Bitmap image = BitmapFactory.decodeFile(photoFile.getAbsolutePath());
imgPhoto.setImageBitmap(resizeBitmap(image, screenWidth));
}
else {
photoLayout.setVisibility(View.GONE);
}
}
});
}
}).start();
}
private Bitmap resizeBitmap(Bitmap image, int screenWidth)
{
// Resize the bitmap so that it fits on the screen, while preserving its aspect ratio.
int imageWidth = image.getWidth();
int imageHeight = image.getHeight();
int imageNewHeight = (imageHeight * screenWidth) / imageWidth;
image = Bitmap.createScaledBitmap(image, screenWidth, imageNewHeight, false);
return image;
}
}
答案 0 :(得分:1)
您应该尝试使用此功能解码文件。此方法使用inSampleSize变量加载位图的缩小版本,从而减少内存消耗。
private Bitmap decodeFile(File f){
Bitmap b = null;
//Decode image size
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
FileInputStream fis = new FileInputStream(f);
BitmapFactory.decodeStream(fis, null, o);
fis.close();
int scale = 1;
if (o.outHeight > IMAGE_MAX_SIZE || o.outWidth > IMAGE_MAX_SIZE) {
scale = (int)Math.pow(2, (int) Math.ceil(Math.log(IMAGE_MAX_SIZE /
(double) Math.max(o.outHeight, o.outWidth)) / Math.log(0.5)));
}
//Decode with inSampleSize
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = scale;
fis = new FileInputStream(f);
b = BitmapFactory.decodeStream(fis, null, o2);
fis.close();
return b;
}
答案 1 :(得分:0)
我遇到了完全相同的问题。我通过广场使用毕加索来解决它。 。Picasso.with(的getContext())负载(imageResId).fit()centerInside()代入(ImageView的);
您必须更改加载方式,但它支持加载(文件f)。