Preventing dead lock in layout inflation

Bug: 143353100
Change-Id: I52d0794aad26c1d1de8cb373f3398f626c15b4af
(cherry picked from commit d1a67d0d72)
This commit is contained in:
Sunny Goyal
2019-11-11 11:08:05 -08:00
parent 992cfbf63d
commit e48b55d86e

View File

@@ -21,12 +21,12 @@ import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.android.launcher3.util.ViewPool.Reusable;
import androidx.annotation.AnyThread;
import androidx.annotation.Nullable;
import androidx.annotation.UiThread;
import com.android.launcher3.util.ViewPool.Reusable;
/**
* Utility class to maintain a pool of reusable views.
* During initialization, views are inflated on the background thread.
@@ -58,14 +58,18 @@ public class ViewPool<T extends View & Reusable> {
Preconditions.assertUIThread();
Handler handler = new Handler();
// LayoutInflater is not thread save as it maintains a global variable 'mConstructorArgs'.
// Create a different copy to use on the background thread.
LayoutInflater inflater = mInflater.cloneInContext(mInflater.getContext());
// Inflate views on a non looper thread. This allows us to catch errors like calling
// "new Handler()" in constructor easily.
new Thread(() -> {
for (int i = 0; i < initialSize; i++) {
T view = inflateNewView();
T view = inflateNewView(inflater);
handler.post(() -> addToPool(view));
}
}).start();
}, "ViewPool-init").start();
}
@UiThread
@@ -94,12 +98,12 @@ public class ViewPool<T extends View & Reusable> {
mCurrentSize--;
return (T) mPool[mCurrentSize];
}
return inflateNewView();
return inflateNewView(mInflater);
}
@AnyThread
private T inflateNewView() {
return (T) mInflater.inflate(mLayoutId, mParent, false);
private T inflateNewView(LayoutInflater inflater) {
return (T) inflater.inflate(mLayoutId, mParent, false);
}
/**