OSDN Git Service

Fix NPE with display lists when view not attached
authorChet Haase <chet@google.com>
Thu, 27 Jan 2011 18:30:25 +0000 (10:30 -0800)
committerChet Haase <chet@google.com>
Thu, 27 Jan 2011 18:30:25 +0000 (10:30 -0800)
There was logic in ViewGroup that assumed that an accelerated
view must always be able to get a display list for any child
that it was drawing. One situation occurred, however, that
caused a problem with this - a contacts activity was started
and not yet attached, but was being asked to render into an
accelerated canvas. We assumed that the child would have a display
list and simply called getDisplayList(). But since that call
returned null, we later deref'd the null object.

The fix is to check whether a child can have a display list
instead of assuming that it can just because the container view
is accelerated.

Change-Id: I7de62fd597ad50720c9585d621bec02e77c171df

core/java/android/view/View.java
core/java/android/view/ViewGroup.java

index c64f564..5e8f31a 100644 (file)
@@ -8227,6 +8227,21 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
      * @hide
      */
     protected void dispatchGetDisplayList() {}
+
+    /**
+     * A view that is not attached or hardware accelerated cannot create a display list.
+     * This method checks these conditions and returns the appropriate result.
+     *
+     * @return true if view has the ability to create a display list, false otherwise.
+     *
+     * @hide
+     */
+    public boolean canHaveDisplayList() {
+        if (mAttachInfo == null || mAttachInfo.mHardwareRenderer == null) {
+            return false;
+        }
+        return true;
+    }
     
     /**
      * <p>Returns a display list that can be used to draw this view again
@@ -8237,7 +8252,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
      * @hide
      */
     public DisplayList getDisplayList() {
-        if (mAttachInfo == null || mAttachInfo.mHardwareRenderer == null) {
+        if (!canHaveDisplayList()) {
             return null;
         }
 
index 1313b78..d0509b2 100644 (file)
@@ -2381,7 +2381,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
                 } else if (layerType == LAYER_TYPE_NONE) {
                     // Delay getting the display list until animation-driven alpha values are
                     // set up and possibly passed on to the view
-                    hasDisplayList = true;
+                    hasDisplayList = child.canHaveDisplayList();
                 }
             }
         }