2011-04-18 65 views
3

在线程(CanvasThread)中出现问题,该线程在我的应用程序中随机点处间歇性地暂停。应用程序中的其他任何内容都会继续按需运行,这只是因为某种原因随机拦截的线程,并没有在屏幕上绘制任何新东西。我注意到Surface.lockCanvasNative()似乎是在块之前调用的最后一个函数,并且第一个函数在之后返回。在图案,例如:Android:间歇性地暂停线程

Surface.lockCanvasNative (Landroid/graphics/Rect)Landroid/graphics/Canvas; @ 26,560 msec ____ 
Surface.lockCanvasNative (Landroid/graphics/Rect)Landroid/graphics/Canvas; @ 40,471 msec ____| 

Surface.lockCanvasNative (Landroid/graphics/Rect)Landroid/graphics/Canvas; @ 40,629 msec ____ 
Surface.lockCanvasNative (Landroid/graphics/Rect)Landroid/graphics/Canvas; @ 54,516 msec ____| 

这是与下面的traceview明显: traceview of frozen thread

我一直在使用CanvasThread.run()下面是否有帮助:

@Override 
public void run() { 

    boolean tellRendererSurfaceChanged = true; 

    /* 
    * This is our main activity thread's loop, we go until 
    * asked to quit. 
    */ 
    while (!mDone) { 
     /* 
     * Update the asynchronous state (window size) 
     */ 
     int w; 
     int h; 
     synchronized (this) { 
      // If the user has set a runnable to run in this thread, 
      // execute it and record the amount of time it takes to 
      // run. 
      if (mEvent != null) { 
       mEvent.run(); 
      } 

      if(needToWait()) { 
       while (needToWait()) { 
        try { 
         wait(); 
        } catch (InterruptedException e) { 

        } 
       } 
      } 
      if (mDone) { 
       break; 
      } 
      tellRendererSurfaceChanged = mSizeChanged; 
      w = mWidth; 
      h = mHeight; 
      mSizeChanged = false; 
     } 


     if (tellRendererSurfaceChanged) { 
      mRenderer.sizeChanged(w, h); 
      tellRendererSurfaceChanged = false; 
     } 

     if ((w > 0) && (h > 0)) { 
      // Get ready to draw. 
      // We record both lockCanvas() and unlockCanvasAndPost() 
      // as part of "page flip" time because either may block 
      // until the previous frame is complete. 

      Canvas canvas = mSurfaceHolder.lockCanvas(); 

      if (canvas != null) { 
       // Draw a frame! 
       mRenderer.drawFrame(canvas);       
       mSurfaceHolder.unlockCanvasAndPost(canvas); 

       //CanvasTestActivity._isAsyncGoTime = true;  
      } 
      else{ 
       Log.v("CanvasSurfaceView.CanvasThread", "canvas == null"); 
      } 
     } 
    } 
} 

只要让我知道,如果我可以提供任何其他有用的信息。我只是在寻找线索,为什么我的线程可能在此时被阻塞?感谢您提前提供任何帮助!

我已经把范围缩小到了mSurfaceHolder.unlockCanvasAndPost(canvas);我在这个调用之前和之后插入了一个日志,并且在应用程序被冻结之后没有记录这个日志;但之前的日志是此线程上最后一次记录的事件。它不会暂停或使用空画布,因为我也为这些实例投掷了日志;在应用程序完成之前,它甚至不会被记录一次。

回答

3

因为我已经找到了我的问题。我不知道为什么,但是因为我不小心忘记了一个早期的asyncTask(),所以有两个人做了大致相同的任务,显然正在努力用相同的变量等这样做。感谢您的指点,但我猜想我只是另一个粗心的错误。

3

我不知道这可能是原因,但SurfaceHolder.lockCanvas()下,它警告说,

如果反复调用此当 表面没有准备好(前 回调.surfaceCreated或 Callback.surfaceDestroyed)之后,您的调用 将被限制为 中的较慢速率,以避免消耗CPU。

如果没有返回空,则该函数 内部保持锁定,直到对应 unlockCanvasAndPost(Canvas)的呼叫, 防止SurfaceView从创建,销毁 ,或修改表面 当正在绘制它 。这可以是 比直接访问 表面更方便,因为您不需要 与 绘图线程进行特殊同步 Callback.surfaceDestroyed。

我不确定CPU启动节流时的阈值是多少。多少个线程刷新画布?

顺便说一句,

if(needToWait()) { 
       while (needToWait()) { 

是多余的

+0

是的,在这种情况下,我可以忽略'if(needToWat())'。我研究过这一点,并且记录了所有异常的表面活动(创建,销毁,暂停,不管...)并且在冻结过程中没有任何异常发生,除了unlockCanvasAndPost()实际上不解锁并将画布发布到屏幕上。至于它持有一个锁,直到相应的'unlockCanvasAndPost(Canvas)'为止,这只是常识而已?这只是防止锁定和解锁之间的操作。这并不意味着锁定在解锁时不会解锁吗? – 2011-04-21 19:49:14