在我的应用程序中,当我尝试启动它时强制关闭并且错误指向“setContentView(R.layout.Menu);”行的布局。在XML文件中,它在我的布局中显示“OutOfMemoryError”图像视图。我真的很困惑。请指导我进一步的行动。
已编辑:
我的应用程序使用数据库,并在第一次解析一些XML数据并插入到Sqlite数据库中。我的Outofmemory问题只在第一次发生。第二次它工作正常。我试过System.gc()。对此有任何疑问。
这是我的日志:
E/dalvikvm-heap(2712): 105376-byte external allocation too large for this process.
VM won't let us allocate 105376 bytes
FATAL EXCEPTION: main
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.Test/com.Test.Menu}: android.view.InflateException: Binary XML file line #13: Error inflating class <unknown>
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1647)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1663)
at android.app.ActivityThread.access$1500(ActivityThread.java:117)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:931)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:130)
at android.app.ActivityThread.main(ActivityThread.java:3683)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:507)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
at dalvik.system.NativeStart.main(Native Method)
Caused by: android.view.InflateException: Binary XML file line #13: Error inflating class <unknown>
at android.view.LayoutInflater.createView(LayoutInflater.java:518)
at com.android.internal.policy.impl.PhoneLayoutInflater.onCreateView(PhoneLayoutInflater.java:56)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:568)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:623)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:626)
at android.view.LayoutInflater.inflate(LayoutInflater.java:408)
at android.view.LayoutInflater.inflate(LayoutInflater.java:320)
at android.view.LayoutInflater.inflate(LayoutInflater.java:276)
at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:207)
at android.app.Activity.setContentView(Activity.java:1657)
at com.Test.Menu.onCreate(Menu.java:32)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1611)
... 11 more
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Constructor.constructNative(Native Method)
at java.lang.reflect.Constructor.newInstance(Constructor.java:415)
at android.view.LayoutInflater.createView(LayoutInflater.java:505)
... 23 more
Caused by: java.lang.OutOfMemoryError: bitmap size exceeds VM budget
at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)
at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:460)
at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:336)
at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:697)
at android.content.res.Resources.loadDrawable(Resources.java:1709)
at android.content.res.TypedArray.getDrawable(TypedArray.java:601)
at android.widget.ImageView.<init>(ImageView.java:118)
at android.widget.ImageView.<init>(ImageView.java:108)
这是我的XML代码:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<RelativeLayout
android:id="@+id/RL_Title"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="8"
android:onClick="onTitleClick" >
<ImageView
android:id="@+id/Img_Title_bg"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="center"
android:src="@drawable/title_bg" />
<Button
android:id="@+id/Btn_Title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginRight="5dp"
android:background="@drawable/title_al"
android:drawableRight="@drawable/pro"
android:gravity="center"
android:onClick="onTitleClick" />
</RelativeLayout>
<RelativeLayout
android:id="@+id/RL_MainMenu"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1" android:onClick="onDoNothing">
<ImageView
android:id="@+id/ImageView01"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="4"
android:src="@drawable/main_bg" android:scaleType="centerCrop"/>
<ImageView
android:id="@+id/Img_logo"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="4"
android:scaleType="center"
android:src="@drawable/logo_al" />
<LinearLayout
android:id="@+id/LI_Menu"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_above="@+id/RL_ExtraOption"
android:layout_alignTop="@+id/Img_logo"
android:layout_margin="2dp"
android:orientation="vertical" >
<ImageButton
android:id="@+id/Img_Buyer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="1dp"
android:layout_weight="1"
android:background="@drawable/bt_blink"
android:onClick="Nextclick"
android:scaleType="fitCenter"
android:soundEffectsEnabled="true"
android:src="@drawable/buyer_icon" />
<ImageButton
android:id="@+id/Img_Seller"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="1dp"
android:layout_weight="1"
android:background="@drawable/bt_blink"
android:onClick="Nextclick"
android:scaleType="fitCenter"
android:src="@drawable/seller_icon" />
<ImageButton
android:id="@+id/Img_Lender"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="1dp"
android:layout_weight="1"
android:background="@drawable/bt_blink"
android:onClick="Nextclick"
android:scaleType="fitCenter"
android:src="@drawable/lender_icon" />
<ImageButton
android:id="@+id/Img_myTitleRep"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="1dp"
android:layout_weight="1"
android:background="@drawable/bt_blink"
android:onClick="Nextclick"
android:scaleType="fitCenter"
android:src="@drawable/my_title_rep_icon_al" />
<ImageButton
android:id="@+id/Img_Setup"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="1dp"
android:layout_weight="1"
android:background="@drawable/bt_blink"
android:onClick="Nextclick"
android:scaleType="fitCenter"
android:src="@drawable/setup_icon" />
</LinearLayout>
<RelativeLayout
android:id="@+id/RL_ExtraOption"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:background="@drawable/main_bottom_bg" >
<TextView
android:id="@+id/txt_RepName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="10dp"
android:textColor="@color/white"
android:textSize="@dimen/font_size" />
<TableRow
android:id="@+id/TR_ContactRep"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:gravity="center" >
<Button
android:id="@+id/Btn_ContactRep"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="3dp"
android:background="@drawable/contact_rep_blink"
android:onClick="ContactRep_Click" />
<Button
android:id="@+id/Btn_MoreOption"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="5dp"
android:background="@drawable/main_more_blink"
android:onClick="onMoreClick" />
</TableRow>
</RelativeLayout>
<LinearLayout
android:id="@+id/ln_Mainmore"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/dialog_bg" android:layout_alignParentBottom="true" android:visibility="gone">
<LinearLayout
android:id="@+id/LinearLayout02"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="3"
android:orientation="vertical" >
</LinearLayout>
<TableLayout
android:id="@+id/TableLayout01"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center" >
<TableRow
android:id="@+id/TableRow04"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="5dp"
android:layout_marginTop="20dp"
android:gravity="center" >
<Button
android:id="@+id/Btn_Rate"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="@drawable/property_blue_blink"
android:onClick="onRate"
android:singleLine="true"
android:text="Rate/Testimonial"
android:textColor="@color/white"
android:textSize="@dimen/font_size"
android:textStyle="bold" />
</TableRow>
<TableRow
android:id="@+id/TableRow01"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="5dp"
android:gravity="center" >
<Button
android:id="@+id/btn_SubFeature"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="@drawable/property_blue_blink"
android:onClick="onSubFeature"
android:singleLine="true"
android:text="Submit A Feature"
android:textColor="@color/white"
android:textSize="@dimen/font_size"
android:textStyle="bold" />
</TableRow>
<TableRow
android:id="@+id/TableRow03"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="5dp"
android:gravity="center" >
<Button
android:id="@+id/Btn_ReferFrnd"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="@drawable/property_blue_blink"
android:onClick="onReferAFrnd"
android:text="Refer A Friend"
android:textColor="@color/white"
android:textSize="@dimen/font_size"
android:textStyle="bold" />
</TableRow>
<TableRow
android:id="@+id/TableRow02"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="5dp"
android:gravity="center" >
<Button
android:id="@+id/Btn_cancel"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="@drawable/property_cancel_blink"
android:onClick="onClose"
android:text="Cancel"
android:textColor="@color/black"
android:textSize="@dimen/font_size"
android:textStyle="bold" />
</TableRow>
</TableLayout>
<LinearLayout
android:id="@+id/linearLayout2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="3"
android:orientation="vertical" >
</LinearLayout>
</LinearLayout>
</RelativeLayout>
答案 0 :(得分:61)
我猜问题不在你的布局中;问题出在代码中的其他地方。并且你可能正在某处泄露背景。
其他可能的原因是你必须在解析XML时创建庞大的多个对象(正如你所提到的,这是在解析XML时第一次出现)。虽然Java有自动垃圾收集方法,但你还是不能完全依赖它。当您不再需要它时,使您的集合实例无效或清除对象内容是一种很好的做法。
但是我仍然准备了一个在Android上处理位图时应该记住的重要点列表。
1)您可以在每个位图上调用recycle并将它们设置为null。 (bitmap.recycle()
将释放此位图使用的所有内存,但它不会使位图对象无效。)
2)您还可以在销毁活动时取消绑定与布局关联的drawables
。请尝试下面给出的代码,并查看此链接link。
private void unbindDrawables(View view) {
if (view.getBackground() != null) {
view.getBackground().setCallback(null);
}
if (view instanceof ViewGroup) {
for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {
unbindDrawables(((ViewGroup) view).getChildAt(i));
}
((ViewGroup) view).removeAllViews();
}
}
// Call this method from onDestroy()
void onDestroy() {
super.onDestroy();
unbindDrawables(findViewById(R.id.RootView));
System.gc();
}
3)您可以将hashmaps
转换为WeakHashmaps
,以便在系统内存不足时释放内存。
4)您可以缩放/调整所有位图。要缩放位图,您可以尝试这样的方法:
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 8;
Bitmap preview_bitmap=BitmapFactory.decodeStream(is, null, options);
此inSampleSize选项可减少内存消耗。
这是一个完整的方法。首先,它在不解码内容本身的情况下读取图像大小。然后它找到最好的inSampleSize值;它应该是2的幂。最后图像被解码。
// Decodes image and scales it to reduce memory consumption
private Bitmap decodeFile(File f){
try {
// Decode image size
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
BitmapFactory.decodeStream(new FileInputStream(f),null,o);
// The new size we want to scale to
final int REQUIRED_SIZE=70;
// Find the correct scale value. It should be the power of 2.
int scale=1;
while(o.outWidth/scale/2 >= REQUIRED_SIZE && o.outHeight/scale/2 >= REQUIRED_SIZE)
scale*=2;
// Decode with inSampleSize
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize=scale;
return BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
}
catch (FileNotFoundException e) {
}
return null;
}
看看这个link.。
5)您可以在整个系统内存不足时接听电话的活动中覆盖onLowMemory()
方法。你可以在那里发布一些资源。
6)您可以制作对象SoftReference
或Weakreference
,以便在低内存条件下释放它们。
我观察到的一个非常常见的内存泄漏是由于内部类的实现以及在Handler
中实现Activity
。 This links talks about the same in more detail
我希望这有助于消除您的问题。
答案 1 :(得分:6)
在旧设备上使用Android ImageView
和大图像时,这是一个典型问题(即使文件大小只有几Kbs)。用于解码图像的名为 skia 的本机图形库根据图像的尺寸分配本机内存,因此文件大小不会直接影响它。
即使您省略了XML布局定义中的src
- 属性,也无法在onCreate()
方法中加载图像,也会触发相同的错误。解决此问题的唯一方法是在inSampleSize
中使用BitmapFactory.decodeStream
在解码过程中直接执行下采样(例如,请参阅Strange out of memory issue while loading an image to a Bitmap object)。这本身就提出了如何确定这个比例因子的问题。
我在处理大型图片时找到的最佳解决方案是将ImageView
替换为WebView
并加载一些最小的HTML,如下所示:
webView.loadUrl("file:///android_res/raw/background.html");
raw/background.html
的内容可能是这样的:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
<style type="text/css">
body {
margin: 0;
}
img {
width: 100%;
height: auto;
display: block;
}
</style>
</head>
<body>
<img src="file:///android_res/drawable/background.png" />
</body>
WebView中使用的WebKit引擎以更有效的方式执行图像加载,因此应该消除这些内存分配错误。
您甚至可以将不同的图像用于drawable-port
和drawable-land
,以用于纵向和横向图像。但是,您必须在clearCache(false)
方法中调用WebView实例上的onDestroy()
,否则将始终使用第一次加载时缓存的图像(禁用WebView实例上的缓存不起作用)。
答案 2 :(得分:4)
许多设备的每个设备都有非常有限和受限的内存。许多旧设备为您的应用程序分配了16MB内存,而一些更现代的设备可能分配24MB甚至32MB(我见过只有14MB的设备)。
每当您将大量图像加载到内存中时,此空间会非常快速地填满,从而导致抛出OutOfMemoryError。要解决这个问题,你应该(如前面的答案所说)将图像缩小为缩略图,只将缩略图保留在设备内存中(减少内存占用)并将图像保存到SDCARD。
您可以从Eclipse中的DDMS布局查看程序使用了多少内存。我相信你也可以覆盖Application类来监听“低内存”警告功能。
当您通过BitmapFactory读取位图时,将BitmapFactory.Option inScaled参数设置为2或4(或适合您的任何内容),以创建更小,内存更少的图像。
通常,只有一种解决方案:使用较小的图像。如果没有代码,很难说出什么是错误的。您可以尝试降低图像尺寸。
答案 3 :(得分:4)
除了人们在这里写的内容之外,我建议观看谷歌的这个视频,它指出一些常见的内存问题以及如何找到导致内存问题的原因:
答案 4 :(得分:4)
在这个问题上花了很多时间后我找到了解决方案! 你需要做的就是要求更多的记忆。 将此代码放在您的Android清单中:
<application>:
把:
android:largeHeap="true"
对我来说很棒! 请注意,此解决方案仅适用于API 11及更高版本。
更多信息here.
答案 5 :(得分:3)
之前我遇到过同样的问题,我在S4安卓4.3上进行调试。 解决方案是:将图像从mdpi文件夹复制到hdpi文件夹(因此它们现在位于两个文件夹中)
我知道很奇怪!但这解决了我的问题。
答案 6 :(得分:2)
它接缝像你的图像是大尺寸所以你可以解码你的图像并使用 android:largeHeap =&#34; true&#34;。在应用程序标记的清单中
答案 7 :(得分:0)
您可能已经完成了上述所有解决方案,但仍尝试一下。 在找到合适的解决方案之前,我迷失了方向。 这可能适用于你的案件(请原谅我)。
myIntent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY | Intent.FLAG_ACTIVITY_CLEAR_TASK); myIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
在你打电话给你的活动之前放置这些。