@Override
 public void resume() {
   if (handler != null && handler.isPrepared()) handler.resume();
   else if (handler == null) {
     restart();
   }
 }
 @Override
 public void prepare(BaseDanmakuParser parser) {
   prepare();
   handler.setParser(parser);
   handler.setCallback(mCallback);
   handler.prepare();
 }
 @Override
 public void resume() {
   if (handler != null && mDrawThread != null && handler.isPrepared()) handler.resume();
   else {
     restart();
   }
 }
 @Override
 public void start(long postion) {
   if (handler == null) {
     prepare();
   } else {
     handler.removeCallbacksAndMessages(null);
   }
   handler.obtainMessage(DrawHandler.START, postion).sendToTarget();
 }
 @Override
 protected void onDraw(Canvas canvas) {
   if ((!mDanmakuVisible) && (!mRequestRender)) {
     super.onDraw(canvas);
     return;
   }
   if (mClearFlag) {
     DrawHelper.clearCanvas(canvas);
     mClearFlag = false;
   } else {
     if (handler != null) {
       RenderingState rs = handler.draw(canvas);
       if (mShowFps) {
         if (mDrawTimes == null) mDrawTimes = new LinkedList<Long>();
         String fps =
             String.format(
                 Locale.getDefault(),
                 "fps %.2f,time:%d s,cache:%d,miss:%d",
                 fps(),
                 getCurrentTime() / 1000,
                 rs.cacheHitCount,
                 rs.cacheMissCount);
         DrawHelper.drawFPS(canvas, fps);
       }
     }
   }
   mRequestRender = false; // 复位
   unlockCanvasAndPost();
 }
 @Override
 public boolean isShown() {
   if (handler == null || !isViewReady()) {
     return false;
   }
   return handler.getVisibility();
 }
 @Override
 public long getCurrentTime() {
   if (handler != null) {
     return handler.geCurrenttTime();
   }
   return 0;
 }
 @Override
 public boolean isPaused() {
   if (handler != null) {
     return handler.isStop();
   }
   return false;
 }
 public void toggle() {
   if (isSurfaceCreated) {
     if (handler == null) start();
     else if (handler.isStop()) {
       resume();
     } else pause();
   }
 }
 @Override
 public void showAndResumeDrawTask(Long position) {
   mDanmakuVisibile = true;
   if (handler == null) {
     return;
   }
   handler.showDanmakus(position);
 }
 @Override
 public void hide() {
   mDanmakuVisibile = false;
   if (handler == null) {
     return;
   }
   handler.hideDanmakus(false);
 }
 @Override
 public long hideAndPauseDrawTask() {
   mDanmakuVisibile = false;
   if (handler == null) {
     return 0;
   }
   return handler.hideDanmakus(true);
 }
 @Override
 protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
   super.onLayout(changed, left, top, right, bottom);
   if (handler != null) {
     handler.notifyDispSizeChanged(right - left, bottom - top);
   }
   isSurfaceCreated = true;
 }
 private void stopDraw() {
   if (handler != null) {
     handler.quit();
     handler = null;
   }
   if (mDrawThread != null) {
     try {
       mDrawThread.join();
     } catch (InterruptedException e) {
       e.printStackTrace();
     }
     mDrawThread.quit();
     mDrawThread = null;
   }
 }
 @Override
 public synchronized long drawDanmakus() {
   if (!isSurfaceCreated) return 0;
   long stime = System.currentTimeMillis();
   if (!isShown()) return -1;
   long dtime = 0;
   Canvas canvas = lockCanvas();
   if (canvas != null) {
     if (handler != null) {
       handler.draw(canvas);
       if (mShowFps) {
         if (mDrawTimes == null) mDrawTimes = new LinkedList<Long>();
         dtime = System.currentTimeMillis() - stime; // not so accurate
         String fps = String.format(Locale.getDefault(), "%02d MS, fps %.2f", dtime, fps());
         DrawHelper.drawFPS(canvas, fps);
       }
     }
     if (isSurfaceCreated) unlockCanvasAndPost(canvas);
   }
   dtime = System.currentTimeMillis() - stime;
   return dtime;
 }
  private void lockCanvas() {
    if (mDanmakuVisible == false) {
      return;
    }
    postInvalidateCompat(); //        设置 mRequestRender = true;
                            // --->invalidate触发onDraw(画完后mRequestRender = false; //复位
                            // 并unlockCanvasAndPost();)
    //                                                                   --->unlockCanvasAndPost中
    // mDrawFinished = true; 标志画完

    /*      synchronized(obj) {
        while(!condition) {
            obj.wait();
        }
        obj.doSomething();
    }
    当线程A获得了obj锁后,发现条件condition不满足,无法继续下一处理,于是线程A就wait() , 放弃对象锁.
            之后在另一线程B中,如果B更改了某些条件,使得线程A的condition条件满足了,就可以唤醒线程A:
    synchronized(obj) {
        condition = true;
        obj.notify();
    }*/
    synchronized (mDrawMonitor) {
      while ((!mDrawFinished) && (handler != null)) {
        try {
          mDrawMonitor.wait(200);
        } catch (InterruptedException e) {
          if (mDanmakuVisible == false || handler == null || handler.isStop()) {
            break;
          } else {
            Thread.currentThread().interrupt();
          }
        }
      }
      mDrawFinished = false; // 复位
    }
  }
 public void addDanmaku(BaseDanmaku item) {
   if (handler != null) {
     handler.addDanmaku(item);
   }
 }
 @Override
 public void removeAllLiveDanmakus() {
   if (handler != null) {
     handler.removeAllLiveDanmakus();
   }
 }
 @Override
 public void clearDanmakusOnScreen() {
   if (handler != null) {
     handler.clearDanmakusOnScreen();
   }
 }
 public void setCallback(Callback callback) {
   mCallback = callback;
   if (handler != null) {
     handler.setCallback(callback);
   }
 }
 @Override
 public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
   if (handler != null) {
     handler.notifyDispSizeChanged(width, height);
   }
 }
 @Override
 public boolean isPrepared() {
   return handler != null && handler.isPrepared();
 }
 public void seekTo(Long ms) {
   if (handler != null) {
     handler.seekTo(ms);
   }
 }
 @Override
 public void pause() {
   if (handler != null) handler.pause();
 }