Java 外部分配太大,无法执行此过程
昨晚我发布了一个关于这个问题的问题,但我认为我解释得不够好,无法得到适当的帮助。所以基本上,我有一个应用程序,你可以按下一个按钮,让你从你的图库中选择一个图像,并在我在应用程序中显示的图像视图中显示它。这一切都很好。但是,当我再次按下按钮并选择其他图片时,应用程序强制关闭 更新现在,如果我从库中的下载照片文件夹中拍摄照片,效果很好,可以随时切换照片。但当我回到相机照片文件夹更改图片时,它会强制关闭 更新2它也适用于我的Gallery应用程序中的任何其他文件夹。“Camera”文件夹中只有一个存在此问题(强制关闭) 更新319660800字节外部分配太大,无法执行此过程。这是问题的根源。有什么方法可以减小所选照片的大小Java 外部分配太大,无法执行此过程,java,android,imageview,gallery,Java,Android,Imageview,Gallery,昨晚我发布了一个关于这个问题的问题,但我认为我解释得不够好,无法得到适当的帮助。所以基本上,我有一个应用程序,你可以按下一个按钮,让你从你的图库中选择一个图像,并在我在应用程序中显示的图像视图中显示它。这一切都很好。但是,当我再次按下按钮并选择其他图片时,应用程序强制关闭 更新现在,如果我从库中的下载照片文件夹中拍摄照片,效果很好,可以随时切换照片。但当我回到相机照片文件夹更改图片时,它会强制关闭 更新2它也适用于我的Gallery应用程序中的任何其他文件夹。“Camera”文件夹中只有一个存在
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);
}
这是日志
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)
11-23 16:33:15.871:D/dalvikvm(9171):GC_外部_ALLOC释放51K,49%释放2793K/5447K,外部20868K/22916K,暂停50ms
11-23 16:33:15.878:E/dalvikvm堆(9171):19660800字节的外部分配对此进程太大。
11-23 16:33:15.886:E/GraphicsJNI(9171):虚拟机不允许我们分配19660800字节
11-23 16:33:15.906:D/dalvikvm(9171):用于MALLOC freed解码的GC返回false
11-23 16:33:15.906:D/AndroidRuntime(9171):关闭虚拟机
11-23 16:33:15.910:W/dalvikvm(9171):threadid=1:线程退出时出现未捕获异常(组=0x40015560)
11-23 16:33:15.937:E/AndroidRuntime(9171):致命异常:主
11-23 16:33:15.937:E/AndroidRuntime(9171):java.lang.OutOfMemory错误:位图大小超出VM预算
11-23 16:33:15.937:E/AndroidRuntime(9171):在android.graphics.BitmapFactory.NativeDecodeseam(本机方法)
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.DecodeSourceStream(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.linearLayoutActivity.onActivityResult(linearLayoutActivity.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.Invokenactive(本机方法)
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):在dalvik.system.NativeStart.main(本机方法)
您收到的错误意味着您正在加载的位图太大。你需要减少取样。有关如何处理此问题的一些重要示例,请参见此问题:
更新:您需要先自己加载位图,然后将该位图设置为ImageView上的图像,而不是告诉ImageView加载哪个URI作为位图。这很简单
要从加载位图,您必须首先将URI转换为包含图像路径的字符串(我认为您可以使用URI.getPath()
,尽管我不确定),然后可以使用以下内容加载位图:
Bitmap b = BitmapFactory.decodeFile(pathToImage);
这将对整个位图进行解码,而不是将位图的采样降低到所需的分辨率。假设您的图像视图为125x125像素,图像为1000x1000像素125/1000=8
所以我们只需要每8个像素解码一次。为此,我们采取以下措施:
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
这很简单,应该可以解决你的记忆问题。请参阅我对这个问题回答的第二部分:以获得更广泛的解释。当应用程序强制关闭时,您可以发布Logcat输出吗?我添加了日志。仅当从“照相机”文件夹切换照片时,应用程序才会强制关闭,所有其他文件夹工作正常。照相机文件夹中的照片似乎太大,导致OOM错误。Android只有16mb的应用堆。我该如何解决这个问题?是否有缩放照片的意图?我不能,以我的生命来说,让任何一个工作。:/(承认——显然,我对这一切都很陌生。)