我有一个应用程序,它采用预览框架并将其保存为图片。它完全正常工作,除了在我退出应用程序并尝试再次运行它之后,它将始终强制关闭并且错误是内存的java.lang.out。谁知道有什么问题?下面是我的代码和我的logcat。
public class SymbolCamera extends Activity implements SurfaceHolder.Callback {
/** Called when the activity is first created. */
Camera camera;
Camera.Parameters params;
SurfaceView surfaceView;
SurfaceHolder surfaceHolder;
boolean previewing = false;
LayoutInflater controlInflater = null;
TextView tv;
int flag = 0;
//int width, height;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.color_camera_main);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
getWindow().setFormat(PixelFormat.UNKNOWN);
surfaceView = (SurfaceView)findViewById(R.id.camerapreview);
surfaceHolder = surfaceView.getHolder();
surfaceHolder.addCallback(this);
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
controlInflater = LayoutInflater.from(getBaseContext());
View viewControl = controlInflater.inflate(R.layout.statistics, null);
LayoutParams layoutParamsControl = new LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.FILL_PARENT);
this.addContentView(viewControl, layoutParamsControl);
tv = (TextView)findViewById(R.id.info);
tv.setText("SymbolCamera");
}
public boolean onCreateOptionsMenu(Menu menu)
{
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.option_menu_symbol, menu);
return true;
}
public boolean onOptionsItemSelected(MenuItem item)
{
Intent intent;
if(camera != null)
{
camera.setPreviewCallback(null);
camera.release();
camera = null;
}
switch(item.getItemId())
{
case R.id.gps:
intent = new Intent(getApplicationContext(), GPSActivity.class).setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
finish();
return true;
case R.id.color:
intent = new Intent(getApplicationContext(), ColorCameraActivity.class).setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
finish();
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
public void onPause() {
super.onPause();
if(camera != null) {
//camera.setPreviewCallback(null);
camera.release();
previewing = false;
}
}
Camera.AutoFocusCallback mAutoFocusCallback = new Camera.AutoFocusCallback() {
@Override
public void onAutoFocus(boolean arg0, Camera mCamera) {
// TODO Auto-generated method stub
}
};
Camera.PreviewCallback mPreviewCallback = new Camera.PreviewCallback() {
@Override
public void onPreviewFrame(byte[] data, Camera mCamera) {
// TODO Auto-generated method stub
if(flag == 5)
{
camera.autoFocus(mAutoFocusCallback);
camera.setPreviewCallback(null);
}
int ARRAY_LENGTH = params.getPreviewSize().width*params.getPreviewSize().height*3/2;
int argb8888[] = new int[ARRAY_LENGTH];
decodeYUV(argb8888, data, params.getPreviewSize().width, params.getPreviewSize().height);
Bitmap bitmap = Bitmap.createBitmap(argb8888, params.getPreviewSize().width, params.getPreviewSize().height, Config.ARGB_8888);
if(flag == 5) {
SymbolDetection symDet = new SymbolDetection(bitmap);
String link = symDet.run();
tv.setText(link);
symDet = null;
}
bitmap.recycle();
flag++;
/*FileOutputStream fos;
try {
fos = new FileOutputStream(String.format(Environment.getExternalStorageDirectory().toString() + "/testImage/%d.jpg", System.currentTimeMillis()));
BufferedOutputStream bos = new BufferedOutputStream(fos);
bitmap.compress(CompressFormat.JPEG, 75, bos);
bos.flush();
bos.close();
fos.close();
bitmap = null;
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}*/
}
};
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
// TODO Auto-generated method stub
/*if(previewing)
{
try
{
camera.setPreviewDisplay(null);
camera.setPreviewCallback(null);
}
catch(IOException e)
{
e.printStackTrace();
}
camera.stopPreview();
camera.release();
previewing = false;
}*/
if(camera != null)
{
try {
tv.setText("start camera");
//params.setPreviewSize(width, height);
camera.setPreviewCallback(mPreviewCallback);
camera.setParameters(params);
camera.setPreviewDisplay(surfaceHolder);
camera.startPreview();
previewing = true;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
@Override
public void surfaceCreated(SurfaceHolder arg0) {
// TODO Auto-generated method stub
camera = Camera.open();
params = camera.getParameters();
//width = params.getPreviewSize().width;
//height = params.getPreviewSize().height;
}
@Override
public void surfaceDestroyed(SurfaceHolder arg0) {
// TODO Auto-generated method stub
if(previewing && camera != null)
{
try {
camera.setPreviewCallback(null);
camera.setPreviewDisplay(null);
camera.stopPreview();
camera.release();
camera = null;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
previewing = false;
}
// decode Y, U, and V values on the YUV 420 buffer described as YCbCr_422_SP by Android
// David Manpearl 081201
public void decodeYUV(int[] out, byte[] fg, int width, int height)
throws NullPointerException, IllegalArgumentException {
int sz = width * height;
if (out == null)
throw new NullPointerException("buffer out is null");
if (out.length < sz)
throw new IllegalArgumentException("buffer out size " + out.length
+ " < minimum " + sz);
if (fg == null)
throw new NullPointerException("buffer 'fg' is null");
if (fg.length < sz)
throw new IllegalArgumentException("buffer fg size " + fg.length
+ " < minimum " + sz * 3 / 2);
int i, j;
int Y, Cr = 0, Cb = 0;
for (j = 0; j < height; j++) {
int pixPtr = j * width;
final int jDiv2 = j >> 1;
for (i = 0; i < width; i++) {
Y = fg[pixPtr];
if (Y < 0)
Y += 255;
if ((i & 0x1) != 1) {
final int cOff = sz + jDiv2 * width + (i >> 1) * 2;
Cb = fg[cOff];
if (Cb < 0)
Cb += 127;
else
Cb -= 128;
Cr = fg[cOff + 1];
if (Cr < 0)
Cr += 127;
else
Cr -= 128;
}
int R = Y + Cr + (Cr >> 2) + (Cr >> 3) + (Cr >> 5);
if (R < 0)
R = 0;
else if (R > 255)
R = 255;
int G = Y - (Cb >> 2) + (Cb >> 4) + (Cb >> 5) - (Cr >> 1)
+ (Cr >> 3) + (Cr >> 4) + (Cr >> 5);
if (G < 0)
G = 0;
else if (G > 255)
G = 255;
int B = Y + Cb + (Cb >> 1) + (Cb >> 2) + (Cb >> 6);
if (B < 0)
B = 0;
else if (B > 255)
B = 255;
out[pixPtr++] = 0xff000000 + (B << 16) + (G << 8) + R;
}
}
}
}
logcat的:
10-13 18:22:29.017: ERROR/AndroidRuntime(32260): FATAL EXCEPTION: main
10-13 18:22:29.017: ERROR/AndroidRuntime(32260): java.lang.OutOfMemoryError: bitmap size exceeds VM budget
10-13 18:22:29.017: ERROR/AndroidRuntime(32260): at android.graphics.Bitmap.nativeCreate(Native Method)
10-13 18:22:29.017: ERROR/AndroidRuntime(32260): at android.graphics.Bitmap.createBitmap(Bitmap.java:513)
10-13 18:22:29.017: ERROR/AndroidRuntime(32260): at android.graphics.Bitmap.createBitmap(Bitmap.java:533)
10-13 18:22:29.017: ERROR/AndroidRuntime(32260): at com.augmented.reality.SymbolCamera$2.onPreviewFrame(SymbolCamera.java:129)
10-13 18:22:29.017: ERROR/AndroidRuntime(32260): at android.hardware.Camera$EventHandler.handleMessage(Camera.java:547)
10-13 18:22:29.017: ERROR/AndroidRuntime(32260): at android.os.Handler.dispatchMessage(Handler.java:99)
10-13 18:22:29.017: ERROR/AndroidRuntime(32260): at android.os.Looper.loop(Looper.java:130)
10-13 18:22:29.017: ERROR/AndroidRuntime(32260): at android.app.ActivityThread.main(ActivityThread.java:3703)
10-13 18:22:29.017: ERROR/AndroidRuntime(32260): at java.lang.reflect.Method.invokeNative(Native Method)
10-13 18:22:29.017: ERROR/AndroidRuntime(32260): at java.lang.reflect.Method.invoke(Method.java:507)
10-13 18:22:29.017: ERROR/AndroidRuntime(32260): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:841)
10-13 18:22:29.017: ERROR/AndroidRuntime(32260): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:599)
10-13 18:22:29.017: ERROR/AndroidRuntime(32260): at dalvik.system.NativeStart.main(Native Method)