diff --git a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
index e7cfc453f54a49ab9d5384c2a9d849b0191feef0..53628f7607e1940d91cd603b9f8fc1276dd34729 100644
--- a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
@@ -236,16 +236,14 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
                 R.styleable.MainKeyboardView_gestureFloatingPreviewTextLingerTimeout, 0);
 
         mGestureFloatingTextDrawingPreview = new GestureFloatingTextDrawingPreview(
-                mDrawingPreviewPlacerView, mainKeyboardViewAttr);
-        mDrawingPreviewPlacerView.addPreview(mGestureFloatingTextDrawingPreview);
+                mainKeyboardViewAttr);
+        mGestureFloatingTextDrawingPreview.setDrawingView(mDrawingPreviewPlacerView);
 
-        mGestureTrailsDrawingPreview = new GestureTrailsDrawingPreview(
-                mDrawingPreviewPlacerView, mainKeyboardViewAttr);
-        mDrawingPreviewPlacerView.addPreview(mGestureTrailsDrawingPreview);
+        mGestureTrailsDrawingPreview = new GestureTrailsDrawingPreview(mainKeyboardViewAttr);
+        mGestureTrailsDrawingPreview.setDrawingView(mDrawingPreviewPlacerView);
 
-        mSlidingKeyInputDrawingPreview = new SlidingKeyInputDrawingPreview(
-                mDrawingPreviewPlacerView, mainKeyboardViewAttr);
-        mDrawingPreviewPlacerView.addPreview(mSlidingKeyInputDrawingPreview);
+        mSlidingKeyInputDrawingPreview = new SlidingKeyInputDrawingPreview(mainKeyboardViewAttr);
+        mSlidingKeyInputDrawingPreview.setDrawingView(mDrawingPreviewPlacerView);
         mainKeyboardViewAttr.recycle();
 
         mMoreKeysKeyboardContainer = LayoutInflater.from(getContext())
diff --git a/java/src/com/android/inputmethod/keyboard/internal/AbstractDrawingPreview.java b/java/src/com/android/inputmethod/keyboard/internal/AbstractDrawingPreview.java
index 3a72aed0dc978f6afa77b0e49d48fe577ad54f24..a194f3dfdb3c124abbf4d5c0fbb6e80f0e167cba 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/AbstractDrawingPreview.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/AbstractDrawingPreview.java
@@ -27,16 +27,19 @@ import com.android.inputmethod.keyboard.PointerTracker;
  * SlidingKeyInputDrawingPreview.
  */
 public abstract class AbstractDrawingPreview {
-    private final View mDrawingView;
+    private View mDrawingView;
     private boolean mPreviewEnabled;
     private boolean mHasValidGeometry;
 
-    protected AbstractDrawingPreview(final View drawingView) {
+    public void setDrawingView(final DrawingPreviewPlacerView drawingView) {
         mDrawingView = drawingView;
+        drawingView.addPreview(this);
     }
 
-    protected final View getDrawingView() {
-        return mDrawingView;
+    protected void invalidateDrawingView() {
+        if (mDrawingView != null) {
+            mDrawingView.invalidate();
+        }
     }
 
     protected final boolean isPreviewEnabled() {
diff --git a/java/src/com/android/inputmethod/keyboard/internal/DrawingPreviewPlacerView.java b/java/src/com/android/inputmethod/keyboard/internal/DrawingPreviewPlacerView.java
index 3b4c4341873df51186ebdf4622915833564077ae..a5d47adb3f7beed83a7431c2f79626f5ab422865 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/DrawingPreviewPlacerView.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/DrawingPreviewPlacerView.java
@@ -46,7 +46,9 @@ public final class DrawingPreviewPlacerView extends RelativeLayout {
     }
 
     public void addPreview(final AbstractDrawingPreview preview) {
-        mPreviews.add(preview);
+        if (mPreviews.indexOf(preview) < 0) {
+            mPreviews.add(preview);
+        }
     }
 
     public void setKeyboardViewGeometry(final int[] originCoords, final int width,
diff --git a/java/src/com/android/inputmethod/keyboard/internal/GestureFloatingTextDrawingPreview.java b/java/src/com/android/inputmethod/keyboard/internal/GestureFloatingTextDrawingPreview.java
index 2fa703083b67a0f3265a15a29c462f35ba0b575e..fd84856b7f07b3ff43ae9ba0906e60e17cc88176 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/GestureFloatingTextDrawingPreview.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/GestureFloatingTextDrawingPreview.java
@@ -23,7 +23,6 @@ import android.graphics.Paint.Align;
 import android.graphics.Rect;
 import android.graphics.RectF;
 import android.text.TextUtils;
-import android.view.View;
 
 import com.android.inputmethod.keyboard.PointerTracker;
 import com.android.inputmethod.latin.R;
@@ -49,6 +48,7 @@ public class GestureFloatingTextDrawingPreview extends AbstractDrawingPreview {
         public final float mGesturePreviewHorizontalPadding;
         public final float mGesturePreviewVerticalPadding;
         public final float mGesturePreviewRoundRadius;
+        public final int mDisplayWidth;
 
         private final int mGesturePreviewTextSize;
         private final int mGesturePreviewTextColor;
@@ -72,6 +72,7 @@ public class GestureFloatingTextDrawingPreview extends AbstractDrawingPreview {
                     R.styleable.MainKeyboardView_gestureFloatingPreviewVerticalPadding, 0.0f);
             mGesturePreviewRoundRadius = mainKeyboardViewAttr.getDimension(
                     R.styleable.MainKeyboardView_gestureFloatingPreviewRoundRadius, 0.0f);
+            mDisplayWidth = mainKeyboardViewAttr.getResources().getDisplayMetrics().widthPixels;
 
             final Paint textPaint = getTextPaint();
             final Rect textRect = new Rect();
@@ -100,9 +101,8 @@ public class GestureFloatingTextDrawingPreview extends AbstractDrawingPreview {
     private SuggestedWords mSuggestedWords = SuggestedWords.EMPTY;
     private final int[] mLastPointerCoords = CoordinateUtils.newInstance();
 
-    public GestureFloatingTextDrawingPreview(final View drawingView, final TypedArray typedArray) {
-        super(drawingView);
-        mParams = new GesturePreviewTextParams(typedArray);
+    public GestureFloatingTextDrawingPreview(final TypedArray mainKeyboardViewAttr) {
+        mParams = new GesturePreviewTextParams(mainKeyboardViewAttr);
     }
 
     @Override
@@ -149,7 +149,7 @@ public class GestureFloatingTextDrawingPreview extends AbstractDrawingPreview {
      */
     protected void updatePreviewPosition() {
         if (mSuggestedWords.isEmpty() || TextUtils.isEmpty(mSuggestedWords.getWord(0))) {
-            getDrawingView().invalidate();
+            invalidateDrawingView();
             return;
         }
         final String text = mSuggestedWords.getWord(0);
@@ -163,10 +163,9 @@ public class GestureFloatingTextDrawingPreview extends AbstractDrawingPreview {
         final float rectWidth = textWidth + hPad * 2.0f;
         final float rectHeight = textHeight + vPad * 2.0f;
 
-        final int displayWidth = getDrawingView().getResources().getDisplayMetrics().widthPixels;
         final float rectX = Math.min(
                 Math.max(CoordinateUtils.x(mLastPointerCoords) - rectWidth / 2.0f, 0.0f),
-                displayWidth - rectWidth);
+                mParams.mDisplayWidth - rectWidth);
         final float rectY = CoordinateUtils.y(mLastPointerCoords)
                 - mParams.mGesturePreviewTextOffset - rectHeight;
         rectangle.set(rectX, rectY, rectX + rectWidth, rectY + rectHeight);
@@ -174,6 +173,6 @@ public class GestureFloatingTextDrawingPreview extends AbstractDrawingPreview {
         mPreviewTextX = (int)(rectX + hPad + textWidth / 2.0f);
         mPreviewTextY = (int)(rectY + vPad) + textHeight;
         // TODO: Should narrow the invalidate region.
-        getDrawingView().invalidate();
+        invalidateDrawingView();
     }
 }
diff --git a/java/src/com/android/inputmethod/keyboard/internal/GestureTrailsDrawingPreview.java b/java/src/com/android/inputmethod/keyboard/internal/GestureTrailsDrawingPreview.java
index 72628e38ab5b28d73586a0ac93c85bcea0d8afae..f7bd7efe0263bb1d70f87b46097ed5b0539fb352 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/GestureTrailsDrawingPreview.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/GestureTrailsDrawingPreview.java
@@ -24,17 +24,15 @@ import android.graphics.Paint;
 import android.graphics.PorterDuff;
 import android.graphics.PorterDuffXfermode;
 import android.graphics.Rect;
-import android.os.Message;
+import android.os.Handler;
 import android.util.SparseArray;
-import android.view.View;
 
 import com.android.inputmethod.keyboard.PointerTracker;
-import com.android.inputmethod.latin.utils.LeakGuardHandlerWrapper;
 
 /**
  * Draw preview graphics of multiple gesture trails during gesture input.
  */
-public final class GestureTrailsDrawingPreview extends AbstractDrawingPreview {
+public final class GestureTrailsDrawingPreview extends AbstractDrawingPreview implements Runnable {
     private final SparseArray<GestureTrailDrawingPoints> mGestureTrails = new SparseArray<>();
     private final GestureTrailDrawingParams mDrawingParams;
     private final Paint mGesturePaint;
@@ -47,45 +45,10 @@ public final class GestureTrailsDrawingPreview extends AbstractDrawingPreview {
     private final Rect mDirtyRect = new Rect();
     private final Rect mGestureTrailBoundsRect = new Rect(); // per trail
 
-    private final DrawingHandler mDrawingHandler;
+    private final Handler mDrawingHandler = new Handler();
 
-    private static final class DrawingHandler
-            extends LeakGuardHandlerWrapper<GestureTrailsDrawingPreview> {
-        private static final int MSG_UPDATE_GESTURE_TRAIL = 0;
-
-        private final GestureTrailDrawingParams mDrawingParams;
-
-        public DrawingHandler(final GestureTrailsDrawingPreview ownerInstance,
-                final GestureTrailDrawingParams drawingParams) {
-            super(ownerInstance);
-            mDrawingParams = drawingParams;
-        }
-
-        @Override
-        public void handleMessage(final Message msg) {
-            final GestureTrailsDrawingPreview preview = getOwnerInstance();
-            if (preview == null) {
-                return;
-            }
-            switch (msg.what) {
-            case MSG_UPDATE_GESTURE_TRAIL:
-                preview.getDrawingView().invalidate();
-                break;
-            }
-        }
-
-        public void postUpdateGestureTrailPreview() {
-            removeMessages(MSG_UPDATE_GESTURE_TRAIL);
-            sendMessageDelayed(obtainMessage(MSG_UPDATE_GESTURE_TRAIL),
-                    mDrawingParams.mUpdateInterval);
-        }
-    }
-
-    public GestureTrailsDrawingPreview(final View drawingView,
-            final TypedArray mainKeyboardViewAttr) {
-        super(drawingView);
+    public GestureTrailsDrawingPreview(final TypedArray mainKeyboardViewAttr) {
         mDrawingParams = new GestureTrailDrawingParams(mainKeyboardViewAttr);
-        mDrawingHandler = new DrawingHandler(this, mDrawingParams);
         final Paint gesturePaint = new Paint();
         gesturePaint.setAntiAlias(true);
         gesturePaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC));
@@ -153,6 +116,12 @@ public final class GestureTrailsDrawingPreview extends AbstractDrawingPreview {
         return needsUpdatingGestureTrail;
     }
 
+    @Override
+    public void run() {
+        // Update preview.
+        invalidateDrawingView();
+    }
+
     /**
      * Draws the preview
      * @param canvas The canvas where the preview is drawn.
@@ -167,7 +136,8 @@ public final class GestureTrailsDrawingPreview extends AbstractDrawingPreview {
         final boolean needsUpdatingGestureTrail = drawGestureTrails(
                 mOffscreenCanvas, mGesturePaint, mDirtyRect);
         if (needsUpdatingGestureTrail) {
-            mDrawingHandler.postUpdateGestureTrailPreview();
+            mDrawingHandler.removeCallbacks(this);
+            mDrawingHandler.postDelayed(this, mDrawingParams.mUpdateInterval);
         }
         // Transfer offscreen buffer to screen.
         if (!mDirtyRect.isEmpty()) {
@@ -199,6 +169,6 @@ public final class GestureTrailsDrawingPreview extends AbstractDrawingPreview {
         trail.addStroke(tracker.getGestureStrokeDrawingPoints(), tracker.getDownTime());
 
         // TODO: Should narrow the invalidate region.
-        getDrawingView().invalidate();
+        invalidateDrawingView();
     }
 }
diff --git a/java/src/com/android/inputmethod/keyboard/internal/SlidingKeyInputDrawingPreview.java b/java/src/com/android/inputmethod/keyboard/internal/SlidingKeyInputDrawingPreview.java
index 76cb8916000469b3cca666e701d21a13f1942348..ef4c74d61b11c4207b36782b521682043ce39e0d 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/SlidingKeyInputDrawingPreview.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/SlidingKeyInputDrawingPreview.java
@@ -20,7 +20,6 @@ import android.content.res.TypedArray;
 import android.graphics.Canvas;
 import android.graphics.Paint;
 import android.graphics.Path;
-import android.view.View;
 
 import com.android.inputmethod.keyboard.PointerTracker;
 import com.android.inputmethod.latin.R;
@@ -28,6 +27,11 @@ import com.android.inputmethod.latin.utils.CoordinateUtils;
 
 /**
  * Draw rubber band preview graphics during sliding key input.
+ *
+ * @attr ref R.styleable#MainKeyboardView_slidingKeyInputPreviewColor
+ * @attr ref R.styleable#MainKeyboardView_slidingKeyInputPreviewWidth
+ * @attr ref R.styleable#MainKeyboardView_slidingKeyInputPreviewBodyRatio
+ * @attr ref R.styleable#MainKeyboardView_slidingKeyInputPreviewShadowRatio
  */
 public final class SlidingKeyInputDrawingPreview extends AbstractDrawingPreview {
     private final float mPreviewBodyRadius;
@@ -40,9 +44,7 @@ public final class SlidingKeyInputDrawingPreview extends AbstractDrawingPreview
     private final RoundedLine mRoundedLine = new RoundedLine();
     private final Paint mPaint = new Paint();
 
-    public SlidingKeyInputDrawingPreview(final View drawingView,
-            final TypedArray mainKeyboardViewAttr) {
-        super(drawingView);
+    public SlidingKeyInputDrawingPreview(final TypedArray mainKeyboardViewAttr) {
         final int previewColor = mainKeyboardViewAttr.getColor(
                 R.styleable.MainKeyboardView_slidingKeyInputPreviewColor, 0);
         final float previewRadius = mainKeyboardViewAttr.getDimension(
@@ -69,7 +71,7 @@ public final class SlidingKeyInputDrawingPreview extends AbstractDrawingPreview
 
     public void dismissSlidingKeyInputPreview() {
         mShowsSlidingKeyInputPreview = false;
-        getDrawingView().invalidate();
+        invalidateDrawingView();
     }
 
     /**
@@ -99,6 +101,6 @@ public final class SlidingKeyInputDrawingPreview extends AbstractDrawingPreview
         tracker.getDownCoordinates(mPreviewFrom);
         tracker.getLastCoordinates(mPreviewTo);
         mShowsSlidingKeyInputPreview = true;
-        getDrawingView().invalidate();
+        invalidateDrawingView();
     }
 }