-1

キャンバス上の Android ペインティングにスレッドがあります。すべて正常に動作しますが、戻るボタンを押すと、スレッドがまだその時点で null であるキャンバスに描画しようとするため、アプリがクラッシュします。コードから、スレッドがそのコードに到達することはもうないはずです。

戻るボタンを押すと、Surface が破棄されます。

public void surfaceDestroyed(SurfaceHolder holder) 
{
    boolean retry = true;
    thread.setRunning(false);
    while (retry) 
    {
        try 
        {
            thread.join();
            retry = false;
        } 
        catch (InterruptedException e) 
        {
        }
    }
}

上でわかるように、thread.setRunning を false に設定すると、私のスレッドはこれを行います

  public void run() 
  {
      while (run) 
      {
          Canvas c = null;
          try 
          {
              c = sh.lockCanvas(null);
              synchronized (sh) 
              {
                  doDraw(c);
              }
          } 
          finally 
          {
              if (c != null) 
              {
                  sh.unlockCanvasAndPost(c);
              }
          }
    }
  }

この var を false に設定するとすぐに while ループが停止するはずですが、それでも doDraw() メソッドに入ります。doDraw (ここで null ポインターの例外が発生します) がまだ呼び出されている理由がわかりません。アイデアはありますか?

4

3 に答える 3

0

Thread#joinスレッドを強制終了するのではなく、スレッドが終了するのを待つだけです。またはrun=falseなどのメソッドを設定または使用して、スレッド内のループを中断する必要があります。それらは推奨されておらず、基本的に使用すべきではありません。stopinterrupt

于 2013-10-09T22:10:57.067 に答える
0

私は Android の専門家ではなく初心者ですが、同期ブロックの拡張についてはどうですか (値を読み取り、その値を 1 つのアトム操作として使用する必要があります)。

          synchronized (sh) 
          {
               c = sh.lockCanvas(null);                  
               doDraw(c);
          }

さらに、アクティビティの onStop または onDestroy メソッドで、追加のスレッドを停止/破棄できますか?

最終的にブロックすることについても疑問に思っています。おそらくそれも同期する必要がありますか?わからない...

于 2013-10-09T22:06:59.183 に答える
0

それがうまくいくかどうかはわかりませんが、IntentServiceで同じタスクを実行できます。

アクティビティの終了中に IntentService が停止します。問題が解決する可能性があります。doDraw メソッドで描画用のハンドラーを使用していると思いますが、間違っていますか? 感想と結果教えてください

于 2013-10-09T22:09:57.130 に答える