user1661263
user1661263

Reputation:

Changing the activity from portrait to landscape and back multiple times (i.e., 5-15 times in a row) crashes the app

Changing the view on the page from portrait to landscape and back multiple times (i.e., 5-15 times in a row) crashes the app. The error text is:

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 

Upvotes: 0

Views: 539

Answers (2)

wsanville
wsanville

Reputation: 37516

You're getting an OutOfMemoryError. What is your activity like? What version of Android are you using? Do you have large bitmaps or a WebView on your activity?

You'll need to give more info, or try and spot memory leaks yourself. Eclipse Memory Analyzer is a good tool to help. You can try to see if anything is holding a reference to your activities that are being destroyed, which will prevent them from being garbage collected. This blog post gives some basic usage tips.

Update: Each AsyncTask instance is probably holding onto a reference to its host activity. This is especially true if your AsynTask is a non-static inner class of your activity. So, as you rotate, new tasks will be fired off, and any existing tasks will keep running unless you explicitly do something to stop them.

If these tasks hang on to a reference to their host activity, you will likely have memory problems.

For a solution to this, see Mark Murphy's blog post.

The sample project shows an AsyncTask implementation as a static inner class. The task is returned in onRetainNonConfigurationInstance(), and the hosting Activity is responsible for making sure the AsyncTask knew the right Activity instance to use, before and after the orientation change.

Basically, you need to make sure you properly "detach" your host activity that will be destroyed from your task. From there, its up to you. You can attempt to pass the running task from your old activity to new, or you can try to force it to stop running. The key here is to not use an inner class for your AsynTask unless it is static.

Upvotes: 3

yrajabi
yrajabi

Reputation: 647

You are probably getting OutOfMemoryException because some object (in most cases, bitmap) is not destroyed/released when activities destory and recreate.

First examine your code to find and remove memory leaks, if any.

Then if you have large bitmap or background in your activity, try to extend your activity from this class: (It worked for me)

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;
}

It will try to null any drawable when an activity is destroying. Not a standard and nice way, but at least it worked for me, when I was getting OOM after just 2 rotations!

Upvotes: -1

Related Questions