Imageview 上的 Android 大图像在 OOM 错误时使应用程序崩溃



下面的代码允许用户从他们的图库中挑选4张图像并上传到服务器。目前它正在上传所有 4 张小图像,但当我尝试大图像时,它会因 OOM 错误而崩溃。

即使我尝试加载 2 个大图像,当我在 OOM 错误时加载大图像时,应用程序也会崩溃。处理此类问题的最有效方法是什么?我已经阅读了这个Android位图,但我似乎不知道如何在我的四个图像代码中实现。我尝试过毕加索,但该应用程序的行为仍然与上面相同(同上(。


SelectImageGallery1 = (Button)findViewById(R.id.buttonSelect1);
SelectImageGallery2 = (Button)findViewById(R.id.buttonSelect2);
SelectImageGallery3 = (Button)findViewById(R.id.buttonSelect3);
SelectImageGallery4 = (Button)findViewById(R.id.buttonSelect4);
UploadImageServer = (Button)findViewById(R.id.buttonUpload);
SelectImageGallery1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select Image1 From Gallery"), 1);
}
});
SelectImageGallery2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select Image4 From Gallery"), 2);
}
});
SelectImageGallery3.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select Image3 From Gallery"), 3);
}
});
SelectImageGallery4.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select Image4 From Gallery"), 4);
}
});
UploadImageServer.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
GetImageNameEditText1 = imageName1.getText().toString();
GetImageNameEditText2 = imageName2.getText().toString();
GetImageNameEditText3 = imageName3.getText().toString();
GetImageNameEditText4 = imageName4.getText().toString();
ImageUploadToServerFunction();
}
});
}

@Override
protected void onActivityResult(int RC, int RQC, Intent I) {
super.onActivityResult(RC, RQC, I);
if (RC == 1&&RQC == RESULT_OK&&I != null&&I.getData() != null) {
Uri uri = I.getData();
try {
bitmap1 = MediaStore.Images.Media.getBitmap(getContentResolver(), uri);
imageView1.setImageBitmap(bitmap1);
} catch (IOException e) {
e.printStackTrace();
}
}
if (RC == 2 && RQC == RESULT_OK && I != null && I.getData() != null) {
Uri uri = I.getData();
try {
bitmap2 = MediaStore.Images.Media.getBitmap(getContentResolver(), uri);
//bitmap1 = MediaStore.Images.Media.getBitmap(getContentResolver(), filePath);
imageView2.setImageBitmap(bitmap2);
} catch (IOException e) {
e.printStackTrace();
}
}
if (RC == 3 && RQC == RESULT_OK && I != null && I.getData() != null) {
Uri uri = I.getData();
byte[] imageAsBytes=null;
try {
bitmap3 = MediaStore.Images.Media.getBitmap(getContentResolver(), uri);
//bitmap1 = MediaStore.Images.Media.getBitmap(getContentResolver(), filePath);
imageView3.setImageBitmap(bitmap3);
} catch (IOException e) {
e.printStackTrace();
}
}
if (RC == 4 && RQC == RESULT_OK && I != null && I.getData() != null) {
Uri uri = I.getData();
try {
bitmap4 = MediaStore.Images.Media.getBitmap(getContentResolver(), uri);
//bitmap1 = MediaStore.Images.Media.getBitmap(getContentResolver(), filePath);
imageView4.setImageBitmap(bitmap4);
} catch (IOException e) {
e.printStackTrace();
}
}
}
public String getStringImage1(Bitmap bitmap1){
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap1.compress(Bitmap.CompressFormat.JPEG, 60, baos);
byte[] imageBytes = baos.toByteArray();
String encodedImage1 = Base64.encodeToString(imageBytes, Base64.DEFAULT);
return encodedImage1;
}
public String getStringImage2(Bitmap bitmap2){
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap2.compress(Bitmap.CompressFormat.JPEG, 60, baos);
byte[] imageBytes = baos.toByteArray();
String encodedImage2 = Base64.encodeToString(imageBytes, Base64.DEFAULT);
return encodedImage2;
}
public String getStringImage3(Bitmap bitmap3){
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap3.compress(Bitmap.CompressFormat.JPEG, 60, baos);
byte[] imageBytes = baos.toByteArray();
String encodedImage3 = Base64.encodeToString(imageBytes, Base64.DEFAULT);
return encodedImage3;
}
public String getStringImage4(Bitmap bitmap4){
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap4.compress(Bitmap.CompressFormat.JPEG, 60, baos);
byte[] imageBytes = baos.toByteArray();
String encodedImage4 = Base64.encodeToString(imageBytes, Base64.DEFAULT);
return encodedImage4;
}

这是通过使用 Glide 实现的,如下所示。使用 glide 可确保处理 OOM 错误,并且在加载 30mb 图像时也不会重复这些错误。

@Override
protected void onActivityResult(int RC, int RQC, Intent I) {
super.onActivityResult(RC, RQC, I);
if (RC == 1 && RQC == RESULT_OK && I != null && I.getData() != null) {
Uri uri = I.getData();
RequestOptions options = new RequestOptions()
.format(DecodeFormat.PREFER_ARGB_8888)
.placeholder(R.drawable.ic_launcher_background)
.error(R.drawable.ic_launcher_background);
Glide.with(this)
.setDefaultRequestOptions(options)
.asBitmap()
.load(uri)
.centerInside()
.into(new CustomTarget<Bitmap>(512, 512) {
@Override
public void onResourceReady(@NonNull Bitmap bitmap1, @Nullable Transition<? super Bitmap> transition) {
imageView1.setImageBitmap(bitmap1);
UploadActivity.this.bitmap1 = bitmap1;
}
@Override
public void onLoadCleared(@Nullable Drawable placeholder) {
}
});
}

ByteArrayOutputStream 将所有数据保存在内存中。因此,不能存储大于堆的数据。以第一种方法修改"清单"。

安卓清单.xml

<application
android:largeHeap="true">
</application>

使用 FileInputStream 而不是 ByteArrayOutputStream。

您应该解码位图以减小位图的大小,然后再上传到服务器:

您可以更改大小(reqWidth\reqHeight(由您决定 你可以参考我的Github来获取完整的代码:https://github.com/vancuong0429/ResizeImageUtil/blob/master/ResizeImageUtil

要从onActivityResult((获取文件,您可以参考链接

Android Studio 从 Gallery Intent 获取文件

In onActivityResult((:

@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (RC == 1 && RQC == RESULT_OK && I != null && I.getData() != null) {
Uri uri = I.getData();
// Creating file
// Get the path from the Uri
final String path = getPathFromURI(uri);
if (path != null) {
File yourFile = new File(path);
bitmap1 = decodeBitmapFromFile(yourFile, 512, 512)
}
}
}
public String getPathFromURI(Uri contentUri) {
String res = null;
String[] proj = {MediaStore.Images.Media.DATA};
Cursor cursor = getContentResolver().query(contentUri, proj, null, 
null, null);
if (cursor.moveToFirst()) {
int column_index = 
cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
res = cursor.getString(column_index);
}
cursor.close();
return res;
}
fun decodeBitmapFromFile(imageFile: File, reqWidth: Int, reqHeight: Int): Bitmap {
val options = BitmapFactory.Options()
options.inJustDecodeBounds = true
BitmapFactory.decodeFile(imageFile.absolutePath, options)
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight)
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false
var scaledBitmap = BitmapFactory.decodeFile(imageFile.absolutePath, options)
scaledBitmap = modifyOrientation(scaledBitmap, imageFile.absolutePath)
return scaledBitmap
}

相关内容

最新更新