Workaround memory leak in AsyncLayoutInflater

Bug: 33158143
Test: manual using test apk + hprof inspection
Change-Id: I6cd3845182794b1f68c5d2898df36f4540d3ff26
diff --git a/core-ui/java/android/support/v4/view/AsyncLayoutInflater.java b/core-ui/java/android/support/v4/view/AsyncLayoutInflater.java
index e638d05..e194a50 100644
--- a/core-ui/java/android/support/v4/view/AsyncLayoutInflater.java
+++ b/core-ui/java/android/support/v4/view/AsyncLayoutInflater.java
@@ -169,28 +169,35 @@
         private ArrayBlockingQueue<InflateRequest> mQueue = new ArrayBlockingQueue<>(10);
         private SynchronizedPool<InflateRequest> mRequestPool = new SynchronizedPool<>(10);
 
+        // Extracted to its own method to ensure locals have a constrained liveness
+        // scope by the GC. This is needed to avoid keeping previous request references
+        // alive for an indeterminate amount of time, see b/33158143 for details
+        public void runInner() {
+            InflateRequest request;
+            try {
+                request = mQueue.take();
+            } catch (InterruptedException ex) {
+                // Odd, just continue
+                Log.w(TAG, ex);
+                return;
+            }
+
+            try {
+                request.view = request.inflater.mInflater.inflate(
+                        request.resid, request.parent, false);
+            } catch (RuntimeException ex) {
+                // Probably a Looper failure, retry on the UI thread
+                Log.w(TAG, "Failed to inflate resource in the background! Retrying on the UI"
+                        + " thread", ex);
+            }
+            Message.obtain(request.inflater.mHandler, 0, request)
+                    .sendToTarget();
+        }
+
         @Override
         public void run() {
             while (true) {
-                InflateRequest request;
-                try {
-                    request = mQueue.take();
-                } catch (InterruptedException ex) {
-                    // Odd, just continue
-                    Log.w(TAG, ex);
-                    continue;
-                }
-
-                try {
-                    request.view = request.inflater.mInflater.inflate(
-                            request.resid, request.parent, false);
-                } catch (RuntimeException ex) {
-                    // Probably a Looper failure, retry on the UI thread
-                    Log.w(TAG, "Failed to inflate resource in the background! Retrying on the UI"
-                            + " thread", ex);
-                }
-                Message.obtain(request.inflater.mHandler, 0, request)
-                        .sendToTarget();
+                runInner();
             }
         }