2011-04-18 6 views
3

スレッド(CanvasThread)に問題があり、アプリケーション内の任意の点で断続的に一時停止しています。アプリ内の他のすべては、必要に応じて機能し続けます。何らかの理由でランダムにブロックされ、スクリーンに新しいものを描画しません。私は、Surface.lockCanvasNative()がブロックの前に呼び出された最後の関数であるように見えて、最初のものが後で返されたことに気付きました。以下のようなパターンでは:Android:スレッドが間欠的に一時停止します

@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"); 
      } 
     } 
    } 
} 

をするだけなら、私が知っている:それは場合に役立ちます私は以下のCanvasThread.run()を使用している traceview of frozen thread

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で明らかです私は他の有益な情報を提供することができます。私は単にスレッドがなぜこの時点でブロックしているのかという手がかりを探していますか?事前に助けてくれてありがとう!

ブロックを絞り込んでmSurfaceHolder.unlockCanvasAndPost(canvas);にしました。この呼び出しの前後にログを挿入しましたが、アプリケーションがフリーズした後のログは記録されません。前のログはこのスレッドで最後に記録されたイベントです。私はこれらのインスタンスのログも投げたので、空のキャンバスを一時停止したり使用したりしていません。アプリが終了するまで一度でも記録されません。これが理由であることができれば

答えて

3

です。理由は分かりませんが、以前のasyncTask()を完全にコメントアウトするのを忘れてしまったため、2つのタスクがおおよそ同じ作業を行い、同じ変数などで明らかに苦労しました。あなたの指針をありがとう、私の推測では、別の不注意なミスがあっただけです。

3

は私はわからないんだけど、SurfaceHolder.lockCanvas()の下で、それは警告し

、その 表面は コールバックの前に(準備ができていないときは、これを繰り返し呼び出す場合.surfaceCreatedまたは Callback.surfaceDestroyedの後)、 のコールは、CPUを消費しないように、 オーダーでゆっくりと抑制されます。 nullが返されない場合

、この機能 は、内部 対応 unlockCanvasAndPost(キャンバス)呼び出し、 が作成からSurfaceViewを防止 が破壊、またはそれが引かれている間表面 を変更するまでロックを保持しています。これは サーフェスに直接アクセスするよりも便利です。 描画スレッドとの特別な同期を行う必要はありません。 Callback.surfaceDestroyed。

CPUがスロットリングを開始するときのしきい値がわかりません。キャンバスをリフレッシュするスレッドの数はいくつですか?

ところで、

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

は、私は以来、私の問題を考え出した冗長

+0

この場合、私は 'if(needToWat())'を省略することができました。私はこれを調べて、異常な表面活動(作成、破壊、一時停止、何でも)を記録しました...)、unlockCanvasAndPost()が実際にキャンバスをロック解除して画面にポストしないことを除いて、フリーズ中に異常は何も起こりません。対応する 'unlockCanvasAndPost(Canvas)'が関係するまでロックを保持する限り、それはちょうど常識ですね?これは単にロックとロック解除の間の操作を防ぎます。ロックを解除するために呼び出されたときにロックが解除されないという意味ではありませんか? –

関連する問題