Galaxy note 1(基于AOSP的ROM)上的Android中的OutOfMemoryError在尝试稍微提高分辨率时出错
我一直在安卓上处理图像,这已经有好几天了,我似乎无法解决它 在我的应用程序中有一个添加照片按钮。当用户点击它时,她可以从图库中选择一张照片,或者用相机拍摄一张新照片 但是为了避免出现内存错误,我不得不降低分辨率,以至于发送到服务器的图片几乎只不过是一个缩略图 在这一行中,当我将200更改为250时,它给出了提到的错误! 位图缩放=位图.createScaledBitmapbitmap2,200,200,trueGalaxy note 1(基于AOSP的ROM)上的Android中的OutOfMemoryError在尝试稍微提高分辨率时出错,android,bitmap,android-camera,resolution,Android,Bitmap,Android Camera,Resolution,我一直在安卓上处理图像,这已经有好几天了,我似乎无法解决它 在我的应用程序中有一个添加照片按钮。当用户点击它时,她可以从图库中选择一张照片,或者用相机拍摄一张新照片 但是为了避免出现内存错误,我不得不降低分辨率,以至于发送到服务器的图片几乎只不过是一个缩略图 在这一行中,当我将200更改为250时,它给出了提到的错误! 位图缩放=位图.createScaledBitmapbitmap2,200,200,true 该错误发生在Android 4.2+上,而不是较低级别的Android上。它在安卓4
该错误发生在Android 4.2+上,而不是较低级别的Android上。它在安卓4.1上运行得非常好,即使有400400 我的代码哪部分是错的 代码如下:
public class CreatePropertyActivity5 extends ActionBarActivity {
protected static final int SELECT_PICTURE = 1;
private static final int ACTIVITY_REQUEST_CODE_IMAGE = 100;
private static final int IMAGE_DESCRIPTION = 200;
LinearLayout ll;
private List<File> cameraImageFiles;
private JSONRequestForCreatePropertyListing propertyListing;
ImageView imageView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_create_property_5);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
propertyListing = (JSONRequestForCreatePropertyListing) getIntent().getSerializableExtra("JSONRequestForCreatePropertyListing");
CreatePropertListingAsync cplp = new CreatePropertListingAsync(this, propertyListing);
cplp.execute();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.create_property_activity5, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
public void onClickTakePicture(View v) throws IOException {
// Camera.
final List<Intent> cameraIntents = new ArrayList<Intent>();
final Intent captureIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
final PackageManager packageManager = getPackageManager();
final List<ResolveInfo> listCam = packageManager.queryIntentActivities(captureIntent, 0);
cameraImageFiles = new ArrayList<File>();
int i=0;
for(ResolveInfo res : listCam) {
final String packageName = res.activityInfo.packageName;
final Intent intent = new Intent(captureIntent);
intent.setComponent(new ComponentName(res.activityInfo.packageName, res.activityInfo.name));
intent.setPackage(packageName);
intent.putExtra(MediaStore.MEDIA_IGNORE_FILENAME, ".nomedia");
//** below 4 lines put the uri of the camera taken picture to the EXTRA_OUTPUT
File cameraImageOutputFile = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "myFileName");
cameraImageFiles.add(cameraImageOutputFile);
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(cameraImageFiles.get(i)));
i++;
cameraIntents.add(intent);
}
// Filesystem.
final Intent galleryIntent = new Intent();
galleryIntent.setType("image/*");
galleryIntent.setAction(Intent.ACTION_GET_CONTENT);
// Chooser of filesystem options.
final Intent chooserIntent = Intent.createChooser(galleryIntent, "add new");
// Add the camera options.
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, cameraIntents.toArray(new Parcelable[]{}));
startActivityForResult(chooserIntent, ACTIVITY_REQUEST_CODE_IMAGE);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent imageReturnedIntent)
{
ll = (LinearLayout) findViewById(R.id.llCreatePropertyImages);
switch(requestCode) {
// For sending photos to server. We come here from activity51
case IMAGE_DESCRIPTION:
String s = imageReturnedIntent.getStringExtra("key");
//user entered description is in "key"
imageView.setTag(s);
Bitmap bitmap1 = ((BitmapDrawable)imageView.getDrawable()).getBitmap();
ByteArrayOutputStream stream=new ByteArrayOutputStream();
bitmap1.compress(Bitmap.CompressFormat.PNG, 90, stream);
byte[] image=stream.toByteArray();
String img_str = Base64.encodeToString(image, 0);
//This part sends the picture to the server
ArrayList<Photos> photos = new ArrayList<Photos>();
photos.add(new Photos(new Ax(img_str)));
int id = Integer.parseInt((String) ((TextView) findViewById(R.id.txt_property_listing_ID)).getText());
int editPass = Integer.parseInt((String) ((TextView) findViewById(R.id.txt_property_listing_password)).getText());
JSONRequestForAddPhoto jr = new JSONRequestForAddPhoto(id, editPass, photos);
new AddPhotoAsync(this, jr).execute();
break;
//For choosing photos from gallery or taking one with camera
case ACTIVITY_REQUEST_CODE_IMAGE:
if(resultCode == RESULT_OK){
Uri uri = null;
if(imageReturnedIntent == null){ //since we used EXTRA_OUTPUT for camera, so it will be null
for(int i=0;i<cameraImageFiles.size();i++){
if(cameraImageFiles.get(i).exists()){
uri = Uri.fromFile(cameraImageFiles.get(i));
break;
}
}
}
else { // from gallery
uri = imageReturnedIntent.getData();
}
if(uri != null){
imageView = new ImageView(this);
imageView.setPadding(0, 10, 0, 0);
ll.setVisibility(View.VISIBLE);
try {
Bitmap bitmap2 = MediaStore.Images.Media.getBitmap(this.getContentResolver(), uri);
Bitmap scaled = Bitmap.createScaledBitmap(bitmap2, 250, 250, true);
bitmap2.recycle();
imageView.setImageBitmap(scaled);
ll.addView(imageView);
//*** show activity51
Intent i= new Intent(this, CreatePropertyActivity51.class);
i.putExtra("photo", scaled);
startActivityForResult(i,IMAGE_DESCRIPTION);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
我认为你的代码没有错,但可以优化。但是如果你处理一些大图片,我建议你看看这个答案:我看了你的代码,但是你没有按照开发者网站上提到的方式做。 如何:
先试试看 200x200甚至400x400非常小,您可能正在泄漏内存。你在内存中保留了多少图像?错误发生在Android 4.2+上,而不是较低级别的Android上。它在安卓4.1上运行得非常好,即使有400400-不,当你没有足够的内存时,它会出现在任何版本的安卓上。您是否有足够的内存将由许多因素决定,包括进程的堆限制以及您在执行此工作之前在该进程中所做的工作。OutOfMemoryError与Android版本之间没有紧密的联系。您需要的是优化代码,因为当您加载到应用程序中的许多图像时,OutOfMemoryError通常会发生。@rekire:这个活动是我唯一有图像的地方。可以多次调用onClickTakePicture。但我在第一次通话时就出错了。有什么优化建议吗?我循环使用位图。这就是我对优化的全部了解。我的老板会杀了我的。请看一下这个:它可能会有帮助:我已经读过了。我不知道的是如何获得这个剩余,因为我的imageView中仍然没有图像。我应该从uri获取id吗?能做到吗?因为我没有找到任何指南。我的图像是保存在设备上的文件。我拥有的是它们的Uri,如何从Uri实现代码中的这个剩余部分?我没有找到任何可以引导我完成这一过程的东西。@Tina你读过BitmapFactory类吗?始终可以使用BitmapFactory.decodeFile而不是BitmapFactory.decodeResource。
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);
}