메모리 누수가있는 것 같습니다. 카메라를 사용하는 목록 활동이 있습니다. 사진 찍기 만 지금 작업 중입니다 ... 하지만 일부 목록이 부풀어 오르는 경우 일부 메모리 누수가 발생하는 것 같아요. 일부 리소스를 놓친 것 같아요. 이미지 ....)OOM 예외 - VM 예산을 초과하는 비트 맵 크기
나는 그것을 발견 할 수 없었다.
정말 도움이 필요합니다. 여기
은 클래스입니다 : 리스트 활동패키지 org.BJ.Food4All.Activities.NewRecipe;
import org.BJ.Food4All.R;
import org.BJ.Food4All.Recipe;
import org.BJ.Food4All.Recipe.Instruction;
import org.BJ.Food4All.Activities.RecipeBook.RecipeInstructionsListViewAdapter;
import org.BJ.Food4All.Activities.RecipeBook.SharedData;
import org.BJ.Food4All.utils.CameraUtil;
import org.BJ.Food4All.utils.ImageUploadItem;
import android.app.ListActivity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.ContextMenu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.EditText;
public class Instructions extends ListActivity implements OnClickListener
{
private final static String mTAG = "Instructions";
private EditText mInstructionEditText = null;
private RecipeInstructionsListViewAdapter mListViewAdapter = null;
private Recipe mEditRecipe = PrivateResources.GetRecipe();
private CameraUtil mCameraUtil = new CameraUtil(this);
private int mSelectedEntryIndex = -1;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.new_recipe_instruction_tab);
mInstructionEditText = (EditText)findViewById(R.id.newRecipeInstructionEditTextId);
View addInstructionButton = findViewById(R.id.naddInstructionButtonId);
// Sanity check
if(mInstructionEditText == null ||
addInstructionButton == null)
{
Log.e(mTAG, "NULL pointers");
// secure exit
finish();
}
// Set up click listeners for all the buttons
addInstructionButton.setOnClickListener(this);
mListViewAdapter = new RecipeInstructionsListViewAdapter( this,
R.layout.recipes_instruction_list_single_view_entry,
mEditRecipe.GetInstructions());
setListAdapter(mListViewAdapter);
registerForContextMenu(getListView());
}
public void onClick(View v)
{
switch(v.getId())
{
case R.id.naddInstructionButtonId:
AddInstructionToRecipe(v);
break;
default:
Log.e(mTAG, "Invalid ID:" + v.getId());
// secure exit
finish();
}
}
private void AddInstructionToRecipe(View v)
{
String instructionText = mInstructionEditText.getText().toString();
if(instructionText == null)
{
return;
}
Instruction newInstruction = new Instruction( mEditRecipe.GetInstructions().size() + 1, // Index
instructionText, // The instruction
null,
true);
if(mEditRecipe.AddInstruction(newInstruction) != true)
{
// TODO - ERROR
}
else
{
mListViewAdapter.notifyDataSetChanged();
}
}
/*
* (non-Javadoc)
* @see android.app.Activity#onCreateContextMenu(android.view.ContextMenu, android.view.View, android.view.ContextMenu.ContextMenuInfo)
*/
@Override
public void onCreateContextMenu( ContextMenu menu,
View v,
ContextMenuInfo menuInfo)
{
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.instructions_ctx_menu, menu);
super.onCreateContextMenu( menu,
v,
menuInfo);
}
/*
* (non-Javadoc)
* @see android.app.Activity#onContextItemSelected(android.view.MenuItem)
*/
@Override
public boolean onContextItemSelected(MenuItem item)
{
super.onContextItemSelected(item);
AdapterView.AdapterContextMenuInfo menuInfo;
menuInfo = (AdapterView.AdapterContextMenuInfo)item.getMenuInfo();
mSelectedEntryIndex = menuInfo.position;
switch(item.getItemId())
{
case R.id.deleteId:
mEditRecipe.RemoveInstruction(mSelectedEntryIndex);
mListViewAdapter.notifyDataSetChanged();
return true;
case R.id.takePictureId:
mCameraUtil.TakePicture();
return true;
}
return false;
}
/*
* (non-Javadoc)
* @see android.app.Activity#onActivityResult(int, int, android.content.Intent)
*/
@Override
protected void onActivityResult( int requestCode,
int resultCode,
Intent data)
{
String imageLocation = mCameraUtil.onActivityResult( requestCode,
resultCode,
data);
// TODO - switch to parameter passed in the intent!!!! like TakePicture(index);
mEditRecipe.GetInstructions().get(mSelectedEntryIndex).SetInstructionImageLocation(imageLocation);
mSelectedEntryIndex = -1;
// Update the listviewitem with the picture
mListViewAdapter.notifyDataSetChanged();
}
}
어댑터 대 :
package org.BJ.Food4All.Activities.RecipeBook;
import java.util.ArrayList;
import org.BJ.Food4All.R;
import org.BJ.Food4All.Recipe.Instruction;
import org.BJ.Food4All.utils.GlobalDefs;
import android.content.Context;
import android.graphics.Color;
import android.graphics.Typeface;
import android.net.Uri;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
public class RecipeInstructionsListViewAdapter extends ArrayAdapter<Instruction>
{
private Context mContext;
private ArrayList<Instruction> mItems;
private LayoutInflater mInflater;
public RecipeInstructionsListViewAdapter( Context context,
int textViewResourceId,
ArrayList<Instruction> items)
{
super( context,
textViewResourceId,
items);
mContext = context;
mItems = items;
mInflater = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@Override
public View getView( int position,
View convertView,
ViewGroup parent)
{
ViewHolder holder = new ViewHolder();
if (convertView == null)
{
convertView = mInflater.inflate(R.layout.recipes_instruction_list_single_view_entry, null);
}
if(super.getItem(position) != null)
{
holder.instructionIndex = (TextView) convertView.findViewById(R.id.listUp_RecipeInstructionNumberTextBoxId);
holder.instructionText = (TextView) convertView.findViewById(R.id.listUp_RecipeInstructioTextTextBoxId);
holder.instructionImage = (ImageView)convertView.findViewById(R.id.listUp_RecipeInstructionImageViewId);
Typeface tf = Typeface.createFromAsset(mContext.getAssets(), "Eras_Bold.ttf");
holder.instructionIndex.setTypeface(tf);
holder.instructionIndex.setTextSize(30);
holder.instructionIndex.setTextColor(GlobalDefs.GetHeadlineColor());
holder.instructionIndex.setText(Integer.toString(mItems.get(position).getIndex()));
tf = Typeface.createFromAsset(mContext.getAssets(), "Arial.ttf");
holder.instructionText.setTypeface(tf);
holder.instructionText.setTextSize(14);
holder.instructionText.setTextColor(Color.BLACK);
holder.instructionText.setText(mItems.get(position).getText());
String imageLocation = mItems.get(position).GetInstructionImageLocation();
if(imageLocation != null)
{
holder.instructionImage.setImageURI(Uri.parse(imageLocation));
holder.instructionImage.setVisibility(View.VISIBLE);
}
else
{
holder.instructionImage.setVisibility(View.GONE);
}
convertView.setTag(holder);
convertView.setLayoutParams(new ListView.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
}
else
{
}
return convertView;
}
@Override
public boolean isEnabled(int position)
{
return true;
}
static class ViewHolder
{
TextView instructionIndex;
TextView instructionText;
ImageView instructionImage;
}
}
카메라 UTIL :
package org.BJ.Food4All.utils;
import java.io.File;
import org.BJ.Food4All.DB.DBManager;
import android.app.Activity;
import android.content.ContentValues;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Environment;
import android.provider.MediaStore;
import android.util.Log;
//import android.widget.ImageView;
import android.widget.Toast;
public class CameraUtil
{
private static final String mTAG = "CameraUtil";
private static final int PICK_IMAGE = 1;
private static final int CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE = 2;
private Activity mParentActivity = null;
private String mFileName = null; // Storage filename
// private Uri mImageUri = null; // mImageUri is the current activity attribute, define and save it for later usage (also in onSaveInstanceState)
private Bitmap mBitmap = null;
// private ImageView mImageView = null;
private DBManager mDBManager = null;
public CameraUtil(Activity parentActivity)
{
mParentActivity = parentActivity;
mDBManager = new DBManager(parentActivity);
}
/**
* Used by the camera button - for taking a new picture
*/
public void TakePicture()
{
mFileName = mDBManager.GetCurrentImageFilename() + ".jpg";
ContentValues contentValues = new ContentValues();
contentValues.put(MediaStore.Images.Media.TITLE, mFileName);
contentValues.put(MediaStore.Images.Media.DESCRIPTION, "Image capture by camera"); // TODO- update description for recipe name description
// mImageUri = mParentActivity.getContentResolver().insert(
// MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
// contentValues);
//create new Camera Intent
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(getImageFile(mFileName)));//mImageUri);
intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1);
try
{
mParentActivity.startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);
}
catch(Exception e)
{
Toast.makeText(mParentActivity.getApplicationContext(),
"Error while starting Camera!",
Toast.LENGTH_LONG).show();
Log.e(mTAG, "Failed to start camera");
Log.e(mTAG, e.getMessage(), e);
}
}
/**
*
* @param requestCode
* @param resultCode
* @param data
*/
public String onActivityResult(int requestCode, int resultCode, Intent data)
{
String fileManagerString = null;
String selectedImagePath = null;
switch(requestCode)
{
case PICK_IMAGE:
// Used if we want to choose a picture from the gallery
if(resultCode == Activity.RESULT_OK)
{
Uri selectedImageUri = data.getData();
String filePath = null;
try
{
// OI FILE Manager
fileManagerString = selectedImageUri.getPath();
// MEDIA GALLERY
selectedImagePath = getPath(selectedImageUri);
if(selectedImagePath != null)
{
filePath = selectedImagePath;
}
else if(fileManagerString != null)
{
filePath = fileManagerString;
}
else
{
Toast.makeText(mParentActivity.getApplicationContext(),
"Unknown path",
Toast.LENGTH_LONG).show();
Log.e(mTAG, "Unknown image path");
}
if(filePath != null)
{
DecodeFile(filePath);
}
else
{
mBitmap = null;
}
}
catch(Exception e)
{
Toast.makeText(mParentActivity.getApplicationContext(),
"Internal error",
Toast.LENGTH_LONG).show();
Log.e(mTAG, e.getMessage(), e);
}
}
break;
case CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE:
if(resultCode == Activity.RESULT_OK)
{
// Uri selectedImageUri = mImageUri;
String filePath = null;
try
{
// OI FILE Manager
fileManagerString = mFileName;//selectedImageUri.getPath();
// MEDIA GALLERY
// selectedImagePath = mFileName;//getPath(selectedImageUri);
//GlobalData.setUploadedImagePath(selectedImagePath);
// TODO - for uploading the image
// Add image to the recipe images
// ImageUploadItem uploadItem = new ImageUploadItem(selectedImagePath);
// GlobalData.imageUploads.add(uploadItem);
// Get image path on the image
// if(selectedImagePath != null)
// {
// filePath = selectedImagePath;
// }
// else if(fileManagerString != null)
// {
filePath = fileManagerString;
// }
// else
// {
//
// Toast.makeText(mParentActivity.getApplicationContext(),
// "Unknown path",
// Toast.LENGTH_LONG).show();
//
// Log.e(mTAG, "Unknown image path");
// }
if(filePath != null)
{
String p = getImageFile(mFileName).getPath();
DecodeFile(p);//filePath);
}
else
{
mBitmap = null;
}
}
catch(Exception e)
{
Toast.makeText(mParentActivity.getApplicationContext(),
"Internal error",
Toast.LENGTH_LONG).show();
Log.e(mTAG, e.getMessage(), e);
}
}
break;
default:
return null;
}
// TODO Here is where the image is received from either the camera or the gallery and is in the async task
// TODO to go the next activity
return getImageFile(mFileName).getPath();//mFileName;//selectedImagePath;
}
/**
*
* @param uri
* @return
*/
private String getPath(Uri uri)
{
String[] projection = { MediaStore.Images.Media.DATA };
Cursor cursor = mParentActivity.managedQuery(uri,
projection,
null,
null,
null);
if(cursor != null)
{
// HERE YOU WILL GET A NULLPOINTER IF CURSOR IS NULL
// THIS CAN BE, IF YOU USED OI FILE MANAGER FOR PICKING THE MEDIA
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}
else
{
return null;
}
}
/**
*
* @param filePath
*/
private void DecodeFile(String filePath)
{
// Decode image size
BitmapFactory.Options bitmapOptions = new BitmapFactory.Options();
bitmapOptions.inJustDecodeBounds = true;
BitmapFactory.decodeFile(filePath, bitmapOptions);
// The new size we want to scale to
final int REQUIRED_SIZE = 1024;
// Find the correct scale value. It should be the power of 2.
int width_tmp = bitmapOptions.outWidth;
int height_tmp = bitmapOptions.outHeight;
int scale = 1;
while(true)
{
if(width_tmp < REQUIRED_SIZE &&
height_tmp < REQUIRED_SIZE)
{
break;
}
width_tmp /= 2;
height_tmp /= 2;
scale *= 2;
}
// Decode with inSampleSize
BitmapFactory.Options newBitmapOptions = new BitmapFactory.Options();
newBitmapOptions.inSampleSize = scale;
mBitmap = BitmapFactory.decodeFile(filePath, newBitmapOptions);
}
/**
* Gets the picture taken by the camera - to be used in ImageView
*
* @return
*/
public Bitmap GetTakenPictureBitmap()
{
return mBitmap;
}
/**
* Get the image FILE to be used for the picture taken by the camera - from filename String
*
* @param filename - the filename String
* @return The File representing the image file
*/
private File getImageFile(final String filename)
{
//it will return /sdcard/image.tmp
final File path = new File( Environment.getExternalStorageDirectory(),
mParentActivity.getPackageName());
if(!path.exists())
{
path.mkdir();
}
return new File(path, filename);
}
}
사용이 SO ....이 질문은 질문했다 여러 번 검색 .... – Selvin
는 스택 추적을 포함하시기 바랍니다. –