0

将页面上的视图从纵向更改为横向并返回多次(即连续 5-15 次)会使应用程序崩溃。错误文本是:

09-07 16:18:16.976: D/AndroidRuntime(4215): Shutting down VM
09-07 16:18:16.976: W/dalvikvm(4215): threadid=1: thread exiting with uncaught exception (group=0x40a2d1f8)
09-07 16:18:16.992: E/AndroidRuntime(4215): FATAL EXCEPTION: main
09-07 16:18:16.992: E/AndroidRuntime(4215): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.android.mobileTimerClock/com.android.mobileTimerClock.TimeClockDashBoard}: android.view.InflateException: Binary XML file line #3: Error inflating class <unknown>
09-07 16:18:16.992: E/AndroidRuntime(4215): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1956)
09-07 16:18:16.992: E/AndroidRuntime(4215): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1981)
09-07 16:18:16.992: E/AndroidRuntime(4215): at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3351)
09-07 16:18:16.992: E/AndroidRuntime(4215): at android.app.ActivityThread.access$700(ActivityThread.java:123)
09-07 16:18:16.992: E/AndroidRuntime(4215): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1151)
09-07 16:18:16.992: E/AndroidRuntime(4215): at android.os.Handler.dispatchMessage(Handler.java:99)
09-07 16:18:16.992: E/AndroidRuntime(4215): at android.os.Looper.loop(Looper.java:137)
09-07 16:18:16.992: E/AndroidRuntime(4215): at android.app.ActivityThread.main(ActivityThread.java:4424)
09-07 16:18:16.992: E/AndroidRuntime(4215): at java.lang.reflect.Method.invokeNative(Native Method)
09-07 16:18:16.992: E/AndroidRuntime(4215): at java.lang.reflect.Method.invoke(Method.java:511)
09-07 16:18:16.992: E/AndroidRuntime(4215): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
09-07 16:18:16.992: E/AndroidRuntime(4215): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
09-07 16:18:16.992: E/AndroidRuntime(4215): at dalvik.system.NativeStart.main(Native Method)
09-07 16:18:16.992: E/AndroidRuntime(4215): Caused by: android.view.InflateException: Binary XML file line #3: Error inflating class <unknown>
09-07 16:18:16.992: E/AndroidRuntime(4215): at android.view.LayoutInflater.createView(LayoutInflater.java:606)
09-07 16:18:16.992: E/AndroidRuntime(4215): at com.android.internal.policy.impl.PhoneLayoutInflater.onCreateView(PhoneLayoutInflater.java:56)
09-07 16:18:16.992: E/AndroidRuntime(4215): at android.view.LayoutInflater.onCreateView(LayoutInflater.java:653)
09-07 16:18:16.992: E/AndroidRuntime(4215): at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:678)
09-07 16:18:16.992: E/AndroidRuntime(4215): at android.view.LayoutInflater.inflate(LayoutInflater.java:466)
09-07 16:18:16.992: E/AndroidRuntime(4215): at android.view.LayoutInflater.inflate(LayoutInflater.java:396)
09-07 16:18:16.992: E/AndroidRuntime(4215): at android.view.LayoutInflater.inflate(LayoutInflater.java:352)
09-07 16:18:16.992: E/AndroidRuntime(4215): at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:251)
09-07 16:18:16.992: E/AndroidRuntime(4215): at android.app.Activity.setContentView(Activity.java:1835)
09-07 16:18:16.992: E/AndroidRuntime(4215): at com.android.mobileTimerClock.TimeClockDashBoard.onCreate(TimeClockDashBoard.java:488)
09-07 16:18:16.992: E/AndroidRuntime(4215): at android.app.Activity.performCreate(Activity.java:4465)
09-07 16:18:16.992: E/AndroidRuntime(4215): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1049)
09-07 16:18:16.992: E/AndroidRuntime(4215): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1920)
09-07 16:18:16.992: E/AndroidRuntime(4215): ... 12 more
09-07 16:18:16.992: E/AndroidRuntime(4215): Caused by: java.lang.reflect.InvocationTargetException
09-07 16:18:16.992: E/AndroidRuntime(4215): at java.lang.reflect.Constructor.constructNative(Native Method)
09-07 16:18:16.992: E/AndroidRuntime(4215): at java.lang.reflect.Constructor.newInstance(Constructor.java:417)
09-07 16:18:16.992: E/AndroidRuntime(4215): at android.view.LayoutInflater.createView(LayoutInflater.java:586)
09-07 16:18:16.992: E/AndroidRuntime(4215): ... 24 more
09-07 16:18:16.992: E/AndroidRuntime(4215): Caused by: java.lang.OutOfMemoryError
09-07 16:18:16.992: E/AndroidRuntime(4215): at android.graphics.Bitmap.nativeCreate(Native Method)
09-07 16:18:16.992: E/AndroidRuntime(4215): at android.graphics.Bitmap.createBitmap(Bitmap.java:605)
09-07 16:18:16.992: E/AndroidRuntime(4215): at android.graphics.Bitmap.createBitmap(Bitmap.java:551)
09-07 16:18:16.992: E/AndroidRuntime(4215): at android.graphics.Bitmap.createScaledBitmap(Bitmap.java:437)
09-07 16:18:16.992: E/AndroidRuntime(4215): at android.graphics.BitmapFactory.finishDecode(BitmapFactory.java:524)
09-07 16:18:16.992: E/AndroidRuntime(4215): at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:499)
09-07 16:18:16.992: E/AndroidRuntime(4215): at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:351)
09-07 16:18:16.992: E/AndroidRuntime(4215): at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:773)
09-07 16:18:16.992: E/AndroidRuntime(4215): at android.content.res.Resources.loadDrawable(Resources.java:1935)
09-07 16:18:16.992: E/AndroidRuntime(4215): at android.content.res.TypedArray.getDrawable(TypedArray.java:601)
09-07 16:18:16.992: E/AndroidRuntime(4215): at android.view.View.<init>(View.java:2785)
09-07 16:18:16.992: E/AndroidRuntime(4215): at android.view.ViewGroup.<init>(ViewGroup.java:385)
09-07 16:18:16.992: E/AndroidRuntime(4215): at android.widget.FrameLayout.<init>(FrameLayout.java:99)
09-07 16:18:16.992: E/AndroidRuntime(4215): at android.widget.ScrollView.<init>(ScrollView.java:152)
09-07 16:18:16.992: E/AndroidRuntime(4215): at android.widget.ScrollView.<init>(ScrollView.java:148)
09-07 16:18:16.992: E/AndroidRuntime(4215): ... 27 more
09-07 16:18:17.078: W/ActivityManager(181): Force finishing activity com.android.mobileTimerClock/.TimeClockDashBoard 
4

2 回答 2

3

你得到一个OutOfMemoryError. 你的活动是什么样的?你用的是什么版本的安卓?您的活动中是否有大型位图或 WebView?

您需要提供更多信息,或者尝试自己发现内存泄漏。Eclipse Memory Analyzer是一个很好的帮助工具。您可以尝试查看是否有任何东西持有对您正在销毁的活动的引用,这将防止它们被垃圾收集。这篇博文提供了一些基本的使用技巧。

更新:每个AsyncTask实例都可能持有对其宿主活动的引用。如果您AsynTask是活动的非静态内部类,则尤其如此。因此,当您轮换时,新任务将被触发,并且任何现有任务都将继续运行,除非您明确执行某些操作来阻止它们。

如果这些任务依赖于对其主机活动的引用,您可能会遇到内存问题。

有关此问题的解决方案,请参阅 Mark Murphy 的博客文章

示例项目将 AsyncTask 实现显示为静态内部类。该任务在 onRetainNonConfigurationInstance() 中返回,托管 Activity 负责确保 AsyncTask 在方向更改之前和之后知道要使用的正确 Activity 实例。

基本上,您需要确保您正确地“分离”了将从您的任务中销毁的主机活动。从那里开始,由您决定。您可以尝试将正在运行的任务从旧活动传递给新活动,也可以尝试强制它停止运行。这里的关键是不要为你使用内部类,AsynTask除非它是static

于 2012-09-13T18:05:44.433 回答
-1

您可能会得到,OutOfMemoryException因为当活动破坏和重新创建时,某些对象(在大多数情况下,位图)没有被破坏/释放。

首先检查您的代码以查找并消除内存泄漏(如果有)。

然后,如果您的活动中有较大的位图或背景,请尝试从此类扩展您的活动:(它对我有用)

public abstract class AdvancedActivity extends Activity
{

  @Override
  protected void onResume()
  {
    System.gc();
    super.onResume();
  }

  @Override
  protected void onPause()
  {
    super.onPause();
    System.gc();
  }

  @Override
  public void setContentView(int layoutResID)
  {
    ViewGroup mainView = (ViewGroup)
      LayoutInflater.from(this).inflate(layoutResID, null);

    setContentView(mainView);
  }

  @Override
  public void setContentView(View view)
  {
    super.setContentView(view);
    m_contentView = (ViewGroup)view;
  }

  @Override
  public void setContentView(View view, LayoutParams params)
  {
    super.setContentView(view, params);

    m_contentView = (ViewGroup)view;
  }

  @Override
  protected void onDestroy()
  {
    super.onDestroy();

    // Fixes android memory  issue 8488 :
    // http://code.google.com/p/android/issues/detail?id=8488
    nullViewDrawablesRecursive(m_contentView);

    m_contentView = null;
    System.gc();
  }

  private void nullViewDrawablesRecursive(View view)
  {
    if(view != null)
    {
      try
      {
        if (view instanceof ViewGroup) {  
            ViewGroup viewGroup = (ViewGroup)view;
            int childCount = viewGroup.getChildCount();
            for(int index = 0; index < childCount; index++)
            {
              nullViewDrawablesRecursive(viewGroup.getChildAt(index));
            }
        }   
      }
      catch(Exception e)
      {          
      }

      nullViewDrawable(view);
    }    
  }

  private void nullViewDrawable(View view)
  {
    try
    {
      view.setBackgroundDrawable(null);
    }
    catch(Exception e)
    {          
    }

    try
    {
      ImageView imageView = (ImageView)view;
      imageView.setImageDrawable(null);
      imageView.setBackgroundDrawable(null);
    }
    catch(Exception e)
    {          
    }
  }

  // The top level content view.
  private ViewGroup m_contentView = null;
}

当活动正在破坏时,它将尝试使任何可绘制对象为空。这不是一个标准的好方法,但至少它对我有用,当我在 2 次旋转后得到 OOM 时!

于 2012-09-13T18:19:27.030 回答