关于方向变化的InflateException

时间:2016-04-02 00:44:27

标签: java android android-studio android-orientation

每当我更改屏幕方向时,我的应用程序崩溃时会出现以下异常。我相信它与ImageViews有关,导致模拟器耗尽内存,但我无法理解堆栈跟踪。

在ProfileActivity.java中(我希望允许更改方向),我尝试保存和恢复我的ImageViews的实例,但这似乎不起作用:

@Override protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_beer_profile);

    if(savedInstanceState != null){
        ratingImages = (List<ImageView>) savedInstanceState.getSerializable("ratingImages");
    } 
}

@Override protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putSerializable("ratingImages", (Serializable) ratingImages);
}

@Override public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);

}

但是,我得到以下运行时异常:

04-01 17:34:29.836 25455-25455/com.myapp.myapp E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.myapp.myapp, PID: 25455
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.myapp.myapp/com.myapp.myapp.ProfileActivity}: android.view.InflateException: Binary XML file line #269: Binary XML file line #269: Error inflating class <unknown>
  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2416)
  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
  at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:4077)
  at android.app.ActivityThread.-wrap15(ActivityThread.java)
  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1350)
  at android.os.Handler.dispatchMessage(Handler.java:102)
  at android.os.Looper.loop(Looper.java:148)
  at android.app.ActivityThread.main(ActivityThread.java:5417)
  at java.lang.reflect.Method.invoke(Native Method)
  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Caused by: android.view.InflateException: Binary XML file line #269: Binary XML file line #269: Error inflating class <unknown>
  at android.view.LayoutInflater.inflate(LayoutInflater.java:539)
  at android.view.LayoutInflater.inflate(LayoutInflater.java:423)
  at android.view.LayoutInflater.inflate(LayoutInflater.java:374)
  at android.support.v7.app.AppCompatDelegateImplV7.setContentView(AppCompatDelegateImplV7.java:257)
  at android.support.v7.app.AppCompatActivity.setContentView(AppCompatActivity.java:109)
  at com.myapp.myapp.ProfileActivity.onCreate(ProfileActivity.java:46)
  at android.app.Activity.performCreate(Activity.java:6237)
  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107)
  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369)
  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476) 
  at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:4077) 
  at android.app.ActivityThread.-wrap15(ActivityThread.java) 
  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1350) 
  at android.os.Handler.dispatchMessage(Handler.java:102) 
  at android.os.Looper.loop(Looper.java:148) 
  at android.app.ActivityThread.main(ActivityThread.java:5417) 
  at java.lang.reflect.Method.invoke(Native Method) 
  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 
Caused by: android.view.InflateException: Binary XML file line #269: Error inflating class <unknown>
  at android.view.LayoutInflater.createView(LayoutInflater.java:645)
  at com.android.internal.policy.PhoneLayoutInflater.onCreateView(PhoneLayoutInflater.java:58)
  at android.view.LayoutInflater.onCreateView(LayoutInflater.java:694)
  at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:762)
  at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:704)
  at android.view.LayoutInflater.rInflate(LayoutInflater.java:835)
  at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:798)
  at android.view.LayoutInflater.rInflate(LayoutInflater.java:838)
  at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:798)
  at android.view.LayoutInflater.rInflate(LayoutInflater.java:838)
  at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:798)
  at android.view.LayoutInflater.rInflate(LayoutInflater.java:838)
  at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:798)
  at android.view.LayoutInflater.inflate(LayoutInflater.java:515)
  at android.view.LayoutInflater.inflate(LayoutInflater.java:423) 
  at android.view.LayoutInflater.inflate(LayoutInflater.java:374) 
  at android.support.v7.app.AppCompatDelegateImplV7.setContentView(AppCompatDelegateImplV7.java:257) 
  at android.support.v7.app.AppCompatActivity.setContentView(AppCompatActivity.java:109) 
  at com.myapp.myapp.ProfileActivity.onCreate(ProfileActivity.java:46) 
  at android.app.Activity.performCreate(Activity.java:6237) 
  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107) 
  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369) 
  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476) 
  at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:4077) 
  at android.app.ActivityThread.-wrap15(ActivityThread.java) 
  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1350) 
  at android.os.Handler.dispatchMessage(Handler.java:102) 
  at android.os.Looper.loop(Looper.java:148) 
  at android.app.ActivityThread.main(ActivityThread.java:5417) 
  at java.lang.reflect.Method.invoke(Native Method) 
  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 
Caused by: java.lang.reflect.InvocationTargetException
  at java.lang.reflect.Constructor.newInstance(Native Method)
  at android.view.LayoutInflater.createView(LayoutInflater.java:619)
  at com.android.internal.policy.PhoneLayoutInflater.onCreateView(PhoneLayoutInflater.java:58) 
  at android.view.LayoutInflater.onCreateView(LayoutInflater.java:694) 
  at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:762) 
  at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:704) 
  at android.view.LayoutInflater.rInflate(LayoutInflater.java:835) 
  at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:798) 
  at android.view.LayoutInflater.rInflate(LayoutInflater.java:838) 
  at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:798) 
  at android.view.LayoutInflater.rInflate(LayoutInflater.java:838) 
  at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:798) 
  at android.view.LayoutInflater.rInflate(LayoutInflater.java:838) 
  at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:798) 
  at android.view.LayoutInflater.inflate(LayoutInflater.java:515) 
  at android.view.LayoutInflater.inflate(LayoutInflater.java:423) 
  at android.view.LayoutInflater.inflate(LayoutInflater.java:374) 
  at android.support.v7.app.AppCompatDelegateImplV7.setContentView(AppCompatDelegateImplV7.java:257) 
  at android.support.v7.app.AppCompatActivity.setContentView(AppCompatActivity.java:109) 
  at com.myapp.myapp.ProfileActivity.onCreate(ProfileActivity.java:46) 
  at android.app.Activity.performCreate(Activity.java:6237) 
  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107) 
  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369) 
  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476) 
  at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:4077) 
  at android.app.ActivityThread.-wrap15(ActivityThread.java) 
  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1350) 
  at android.os.Handler.dispatchMessage(Handler.java:102) 
  at android.os.Looper.loop(Looper.java:148) 
  at android.app.ActivityThread.main(ActivityThread.java:5417) 
  at java.lang.reflect.Method.invoke(Native Method) 
  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 
Caused by: java.lang.OutOfMemoryError: Failed to allocate a 4284912 byte allocation with 2835528 free bytes and 2MB until OOM
  at dalvik.system.VMRuntime.newNonMovableArray(Native Method)
  at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)
  at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:609)
  at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:444)
  at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:1080)
  at android.content.res.Resources.loadDrawableForCookie(Resources.java:2635)
  at android.content.res.Resources.loadDrawable(Resources.java:2540)
  at android.content.res.TypedArray.getDrawable(TypedArray.java:870)
  at android.widget.ImageView.<init>(ImageView.java:152)
  at android.widget.ImageView.<init>(ImageView.java:140)
  at android.widget.ImageView.<init>(ImageView.java:136)
  at java.lang.reflect.Constructor.newInstance(Native Method) 
  at android.view.LayoutInflater.createView(LayoutInflater.java:619) 
  at com.android.internal.policy.PhoneLayoutInflater.onCreateView(PhoneLayoutInflater.java:58) 
  at android.view.LayoutInflater.onCreateView(LayoutInflater.java:694) 
  at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:762) 
  at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:704) 
  at android.view.LayoutInflater.rInflate(LayoutInflater.java:835) 
  at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:798) 
  at android.view.LayoutInflater.rInflate(LayoutInflater.java:838) 
  at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:798) 
  at android.view.LayoutInflater.rInflate(LayoutInflater.java:838) 
  at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:798) 
  at android.view.LayoutInflater.rInflate(LayoutInflater.java:838) 
  at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:798) 
  at android.view.LayoutInflater.inflate(LayoutInflater.java:515) 
  at android.view.LayoutInflater.inflate(LayoutInflater.java:423) 
  at android.view.LayoutInflater.inflate(LayoutInflater.java:374) 
  at android.support.v7.app.AppCompatDelegateImplV7.setContentView(AppCompatDelegateImplV7.java:257) 
  at android.support.v7.app.AppCompatActivity.setContentView(AppCompatActivity.java:109) 
  at com.myapp.myapp.ProfileActivity.onCreate(ProfileActivity.java:46) 
  at android.app.Activity.performCreate(Activity.java:6237) 
  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107) 
  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369) 
  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476) 
  at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:4077) 
  at android.app.ActivityThread.-wrap15(ActivityThread.java) 
  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1350) 
  at android.os.Handler.dispatchMessage(Handler.java:102) 
  at android.os.Looper.loop(Looper.java:148) 
  at android.app.ActivityThread.main(ActivityThread.java:5417) 
  at java.lang.reflect.Method.invoke(Native Method) 
  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 

编辑:我在物理设备上试过这个,它不会崩溃。但是,我仍然想知道在模拟器中如何最好地避免这个问题。我可以想象,模拟器上的内存不足可能意味着我没有正确处理ImageViews的方向更改。

任何帮助将不胜感激。谢谢!

1 个答案:

答案 0 :(得分:2)

  

我认为它与ImageViews有关,导致模拟器耗尽内存

更准确地说,正是您放入ImageView窗口小部件的图像是导致崩溃的直接原因。

  

但是我无法理解堆栈跟踪。

无论你在com.myapp.myapp.ProfileActivity中膨胀的是什么布局,其onCreate()方法(第46行)都有ImageView指向可绘制资源,当加载时,需要4284912字节解码。这相当于1035px x 1035px图像。

这相当大。

此外,你没有足够大的免费内存块。部分原因是因为你已经消耗了大量的内存,因为你总共只有2MB的堆空间可用,更不用说在一个块中了。

  

我尝试像这样保存和恢复我的ImageViews的实例

这是不可能的。

从战术上看,查看布局,找到ImageView窗口小部件,查找哪些窗口具有非常大的图像,然后停止使用这些非常大的图像。您可能还希望确认您正在使用的资源目录,并考虑将较低分辨率版本的图像用于较低密度的屏幕。

从战略上讲,您需要掌握内存消耗的所有权。您可以在Android Studio(或其他地方)中生成堆转储和使用工具,以查看堆中的内容以及占用大量空间的内容。不幸的是,谷歌并没有费心去记录Android Studio中的堆分析工具,但是this bit of documentation涵盖了内存管理的其他方面,而this page涵盖了内存监视器,向您展示了堆的实时图表用法(通过工具栏按钮可以从中触发堆转储)。