From f5e2a62f806f32d5f505f2c1dbc5b99e4a7ce849 Mon Sep 17 00:00:00 2001 From: linyuh Date: Wed, 22 Nov 2017 17:19:06 -0800 Subject: Fix the crash caused by DialpadView's OnPreDrawListener. OnPreDrawListener can be triggered AFTER a device orientation change but BEFORE DialpadView's onDetachedFromWindow() and onFinishInflate() are called, i.e., the listener will attempt to adjust the layout before it is inflated, which results in a crash. This fix is to remove the listener after all keys are adjusted for the first time since no more adjustments will be needed during the rest of DialpadView's lifecycle. Bug: 69665429 Test: DialpadFragmentIntegrationTest PiperOrigin-RevId: 176718488 Change-Id: Iff8a4108c73054a9e76725ef85e2559b90fe5f3e --- java/com/android/dialer/dialpadview/DialpadView.java | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) (limited to 'java/com/android/dialer/dialpadview') diff --git a/java/com/android/dialer/dialpadview/DialpadView.java b/java/com/android/dialer/dialpadview/DialpadView.java index 1d48066ad..e7e3c7cc2 100644 --- a/java/com/android/dialer/dialpadview/DialpadView.java +++ b/java/com/android/dialer/dialpadview/DialpadView.java @@ -503,10 +503,26 @@ public class DialpadView extends LinearLayout { @Override public boolean onPreDraw() { if (!shouldAdjustKeySizes()) { - return true; // Return true to proceed with the current drawing pass. + // Return true to proceed with the current drawing pass. + // Note that we must NOT remove this listener here. The fact that we don't need to adjust + // keys at the moment doesn't mean they won't need adjustments in the future. For example, + // when DialpadFragment is hidden, all keys are of the same size (0) and nothing needs to be + // done. Removing the listener will cost us the ability to adjust them when they reappear. + // It is only safe to remove the listener after adjusting keys for the first time. See the + // comment below for more details. + return true; } adjustKeySizes(); + + // After all keys are adjusted for the first time, no more adjustments will be needed during + // the rest of DialpadView's lifecycle. It is therefore safe to remove this listener. + // Another important reason for removing the listener is that it can be triggered AFTER a + // device orientation change but BEFORE DialpadView's onDetachedFromWindow() and + // onFinishInflate() are called, i.e., the listener will attempt to adjust the layout before + // it is inflated, which results in a crash. + getViewTreeObserver().removeOnPreDrawListener(this); + return false; // Return false to cancel the current drawing pass. } -- cgit v1.2.3