external allocation too large for this process(此过程的外部分配太大)
问题描述
我昨晚发布了一个关于这个问题的问题,但我认为我解释得不够好,无法获得适当的帮助.所以基本上,我有一个应用程序,您可以在其中按下一个按钮,让您从图库中选择图像并将其显示在我在应用程序中显示的 ImageView 中.这一切都很好.但是,当我再次按下按钮并选择不同的图片时,应用程序强制关闭.
更新现在,如果我从图库中的下载照片文件夹中拍摄照片,它可以正常工作,可以随意切换照片.但是当我回到我的相机照片文件夹更改图片时,它会强制关闭.
更新 2 它也适用于我的画廊应用程序中的任何其他文件夹.只有一个有这个问题(强制关闭)在相机"文件夹中
UPDATE 3 19660800 字节的外部分配对于此进程来说太大.导致问题.有什么方法可以减小所选照片的大小?
private static final int SELECT_PICTURE = 1;私有字符串 selectedImagePath;私有 ImageView img;公共无效 onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);设置内容视图(R.layout.main);img = (ImageView)findViewById(R.id.myimageview);((按钮)findViewById(R.id.taptoadd)).setOnClickListener(new OnClickListener() {公共无效 onClick(查看 arg0){意图意图 = new Intent();intent.setType("图片/*");意图.setAction(意图.ACTION_GET_CONTENT);startActivityForResult(Intent.createChooser(intent,"选择图片"), SELECT_PICTURE);}});}public void onActivityResult(int requestCode, int resultCode, Intent data) {if (resultCode == RESULT_OK) {if (requestCode == SELECT_PICTURE) {Uri selectedImageUri = data.getData();selectedImagePath = getPath(selectedImageUri);System.out.println("图像路径:" + selectedImagePath);img.setImageURI(selectedImageUri);}}}公共字符串getPath(Uri uri){字符串 [] 投影 = { MediaStore.Images.Media.DATA };光标 cursor = managedQuery(uri, projection, null, null, null);int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);cursor.moveToFirst();返回 cursor.getString(column_index);}
这是日志
11-23 16:33:15.871: D/dalvikvm(9171): GC_EXTERNAL_ALLOC 释放 51K,49% 释放 2793K/5447K,外部 20868K/22916K,暂停 50ms11-23 16:33:15.878: E/dalvikvm-heap(9171): 19660800 字节的外部分配对于这个进程来说太大了.11-23 16:33:15.886: E/GraphicsJNI(9171): VM 不允许我们分配 19660800 字节11-23 16:33:15.906: D/dalvikvm(9171): GC_FOR_MALLOC freed <1K, 49% free 2792K/5447K, external 1668K/20868K, paused 18ms11-23 16:33:15.906: D/skia(9171):---解码器->解码返回假11-23 16:33:15.906: D/AndroidRuntime(9171): 关闭 VM11-23 16:33:15.910: W/dalvikvm(9171): threadid=1: 线程以未捕获的异常退出 (group=0x40015560)11-23 16:33:15.937:E/AndroidRuntime(9171):致命异常:主要11-23 16:33:15.937: E/AndroidRuntime(9171): java.lang.OutOfMemoryError: 位图大小超出 VM 预算11-23 16:33:15.937: E/AndroidRuntime(9171): 在 android.graphics.BitmapFactory.nativeDecodeStream(Native Method)11-23 16:33:15.937: E/AndroidRuntime(9171): 在 android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:470)11-23 16:33:15.937: E/AndroidRuntime(9171): 在 android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:336)11-23 16:33:15.937: E/AndroidRuntime(9171): 在 android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:697)11-23 16:33:15.937: E/AndroidRuntime(9171): 在 android.graphics.drawable.Drawable.createFromStream(Drawable.java:657)11-23 16:33:15.937: E/AndroidRuntime(9171): 在 android.widget.ImageView.resolveUri(ImageView.java:521)11-23 16:33:15.937: E/AndroidRuntime(9171): 在 android.widget.ImageView.setImageURI(ImageView.java:305)11-23 16:33:15.937: E/AndroidRuntime(9171): 在 snapshot.app.LinearLayoutsActivity.onActivityResult(LinearLayoutsActivity.java:48)11-23 16:33:15.937: E/AndroidRuntime(9171): 在 android.app.Activity.dispatchActivityResult(Activity.java:3908)11-23 16:33:15.937: E/AndroidRuntime(9171): 在 android.app.ActivityThread.deliverResults(ActivityThread.java:2528)11-23 16:33:15.937: E/AndroidRuntime(9171): 在 android.app.ActivityThread.handleSendResult(ActivityThread.java:2574)11-23 16:33:15.937: E/AndroidRuntime(9171): 在 android.app.ActivityThread.access$2000(ActivityThread.java:117)11-23 16:33:15.937: E/AndroidRuntime(9171): 在 android.app.ActivityThread$H.handleMessage(ActivityThread.java:961)11-23 16:33:15.937: E/AndroidRuntime(9171): 在 android.os.Handler.dispatchMessage(Handler.java:99)11-23 16:33:15.937: E/AndroidRuntime(9171): 在 android.os.Looper.loop(Looper.java:130)11-23 16:33:15.937: E/AndroidRuntime(9171): 在 android.app.ActivityThread.main(ActivityThread.java:3683)11-23 16:33:15.937: E/AndroidRuntime(9171): 在 java.lang.reflect.Method.invokeNative(Native Method)11-23 16:33:15.937: E/AndroidRuntime(9171): 在 java.lang.reflect.Method.invoke(Method.java:507)11-23 16:33:15.937: E/AndroidRuntime(9171): 在 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)11-23 16:33:15.937: E/AndroidRuntime(9171): 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)11-23 16:33:15.937: E/AndroidRuntime(9171): at dalvik.system.NativeStart.main(Native Method)
你得到的错误意味着你正在加载的位图太大.您需要对其进行下采样.有关如何处理此问题的一些很好的示例,请参阅此问题:Strange out将图像加载到位图对象时出现内存问题
更新:您需要先自己加载位图,然后将该位图设置为 ImageView 上的图像,而不是告诉 ImageView 将哪个 URI 作为 Bitmap 加载.这很简单.
要从中加载位图,您必须首先将 URI 转换为包含图像路径的字符串(我认为您可以使用 URI.getPath()
虽然我不确定)然后您可以使用以下方式加载位图:
位图 b = BitmapFactory.decodeFile(pathToImage);
这将解码整个位图,而不是您希望将位图下采样到所需的分辨率.假设您的图像视图为 125x125 像素,而您的图像为 1000x1000 像素.125/1000 = 8
所以我们只需要每 8 个像素解码一次.为此,我们执行以下操作:
int inSample = 8;opts = new BitmapFactory.Options();opts.inSampleSize = inSample;位图 b = BitmapFactory.decodeFile(pathToImage, opts);//这个位图将是原始大小的 1/8
它非常简单,应该可以解决您的记忆问题.请参阅我对这个问题的回答的第二部分:Android GalleryView Recycling 以获得更广泛的解释.p>
I posted a question last night about this issue, but I dont think I explained it well enough to get the proper help. So basically, I have an application where you can press a button which will let you select an image from your gallery and show it in an ImageView I have displayed in the app. This all works great. However, when I press the button again and choose a different picture the app force closes.
UPDATE Now, if I take a photo from my downloads photo folder in the gallery it works fine, can switch photos as often as I like. But when I go back to my camera photo folder to change the picture it force closes.
UPDATE 2 It also works fine with any other folder I have in my Gallery app. Only one having this problem (force close) is on the "Camera" Folder
UPDATE 3 19660800-byte external allocation too large for this process. is causing the issue. Any ways on reducing the size of the photos being selected?
private static final int SELECT_PICTURE = 1;
private String selectedImagePath;
private ImageView img;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
img = (ImageView)findViewById(R.id.myimageview);
((Button) findViewById(R.id.taptoadd))
.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent,"Select Picture"), SELECT_PICTURE);
}
});
}
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
if (requestCode == SELECT_PICTURE) {
Uri selectedImageUri = data.getData();
selectedImagePath = getPath(selectedImageUri);
System.out.println("Image Path : " + selectedImagePath);
img.setImageURI(selectedImageUri);
}
}
}
public String getPath(Uri uri) {
String[] projection = { MediaStore.Images.Media.DATA };
Cursor cursor = managedQuery(uri, projection, null, null, null);
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}
here is the log
11-23 16:33:15.871: D/dalvikvm(9171): GC_EXTERNAL_ALLOC freed 51K, 49% free 2793K/5447K, external 20868K/22916K, paused 50ms
11-23 16:33:15.878: E/dalvikvm-heap(9171): 19660800-byte external allocation too large for this process.
11-23 16:33:15.886: E/GraphicsJNI(9171): VM won't let us allocate 19660800 bytes
11-23 16:33:15.906: D/dalvikvm(9171): GC_FOR_MALLOC freed <1K, 49% free 2792K/5447K, external 1668K/20868K, paused 18ms
11-23 16:33:15.906: D/skia(9171): --- decoder->decode returned false
11-23 16:33:15.906: D/AndroidRuntime(9171): Shutting down VM
11-23 16:33:15.910: W/dalvikvm(9171): threadid=1: thread exiting with uncaught exception (group=0x40015560)
11-23 16:33:15.937: E/AndroidRuntime(9171): FATAL EXCEPTION: main
11-23 16:33:15.937: E/AndroidRuntime(9171): java.lang.OutOfMemoryError: bitmap size exceeds VM budget
11-23 16:33:15.937: E/AndroidRuntime(9171): at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
11-23 16:33:15.937: E/AndroidRuntime(9171): at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:470)
11-23 16:33:15.937: E/AndroidRuntime(9171): at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:336)
11-23 16:33:15.937: E/AndroidRuntime(9171): at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:697)
11-23 16:33:15.937: E/AndroidRuntime(9171): at android.graphics.drawable.Drawable.createFromStream(Drawable.java:657)
11-23 16:33:15.937: E/AndroidRuntime(9171): at android.widget.ImageView.resolveUri(ImageView.java:521)
11-23 16:33:15.937: E/AndroidRuntime(9171): at android.widget.ImageView.setImageURI(ImageView.java:305)
11-23 16:33:15.937: E/AndroidRuntime(9171): at snapshot.app.LinearLayoutsActivity.onActivityResult(LinearLayoutsActivity.java:48)
11-23 16:33:15.937: E/AndroidRuntime(9171): at android.app.Activity.dispatchActivityResult(Activity.java:3908)
11-23 16:33:15.937: E/AndroidRuntime(9171): at android.app.ActivityThread.deliverResults(ActivityThread.java:2528)
11-23 16:33:15.937: E/AndroidRuntime(9171): at android.app.ActivityThread.handleSendResult(ActivityThread.java:2574)
11-23 16:33:15.937: E/AndroidRuntime(9171): at android.app.ActivityThread.access$2000(ActivityThread.java:117)
11-23 16:33:15.937: E/AndroidRuntime(9171): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:961)
11-23 16:33:15.937: E/AndroidRuntime(9171): at android.os.Handler.dispatchMessage(Handler.java:99)
11-23 16:33:15.937: E/AndroidRuntime(9171): at android.os.Looper.loop(Looper.java:130)
11-23 16:33:15.937: E/AndroidRuntime(9171): at android.app.ActivityThread.main(ActivityThread.java:3683)
11-23 16:33:15.937: E/AndroidRuntime(9171): at java.lang.reflect.Method.invokeNative(Native Method)
11-23 16:33:15.937: E/AndroidRuntime(9171): at java.lang.reflect.Method.invoke(Method.java:507)
11-23 16:33:15.937: E/AndroidRuntime(9171): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
11-23 16:33:15.937: E/AndroidRuntime(9171): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
11-23 16:33:15.937: E/AndroidRuntime(9171): at dalvik.system.NativeStart.main(Native Method)
The error you are getting means that the bitmap you are loading is too big. You need to downsample it. See this question for some great examples on how to deal with this: Strange out of memory issue while loading an image to a Bitmap object
Update: Instead of telling the ImageView which URI to load as a Bitmap, you need to load the bitmap first yourself and then set that bitmap as the image on the ImageView. This is pretty straightforward.
To load a bitmap from you must first convert the URI to a String (I think you can use URI.getPath()
although I'm not sure) that contains the path to the image then you can load the bitmap with:
Bitmap b = BitmapFactory.decodeFile(pathToImage);
This will decode the entire bitmap, instead you want to downsample the bitmap to the desired resolution. Lets say your imageview will be 125x125 pixels and your image is 1000x1000 pixels. 125/1000 = 8
so we only need to decode every 8th pixel. To do this we do the following:
int inSample = 8;
opts = new BitmapFactory.Options();
opts.inSampleSize = inSample;
Bitmap b = BitmapFactory.decodeFile(pathToImage, opts); // this bitmap will be 1/8 the size of the original
Its pretty straight forward and should solve your memory issues. See the 2nd part of my answer to this question: Android GalleryView Recycling for a more extensive explanation.
这篇关于此过程的外部分配太大的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:此过程的外部分配太大
基础教程推荐
- 如何使用 Eclipse 检查调试符号状态? 2022-01-01
- 如何使用 Stream 在集合中拆分奇数和偶数以及两者的总和 2022-01-01
- 如何强制对超级方法进行多态调用? 2022-01-01
- Spring Boot Freemarker从2.2.0升级失败 2022-01-01
- 首次使用 Hadoop,MapReduce Job 不运行 Reduce Phase 2022-01-01
- Java 中保存最后 N 个元素的大小受限队列 2022-01-01
- 由于对所需库 rt.jar 的限制,对类的访问限制? 2022-01-01
- 如何在不安装整个 WTP 包的情况下将 Tomcat 8 添加到 Eclipse Kepler 2022-01-01
- 在螺旋中写一个字符串 2022-01-01
- 如何对 HashSet 进行排序? 2022-01-01