Lunar Landerの例のように、基本的な部分が実装されている SurfaceView 拡張機能があります。つまりrun()
、描画方法Thread
は基本的に次のとおりです。
public void run() {
while (mRun) {
Canvas c;
try {
c = mSurfaceHolder.lockCanvas();
synchronized (mSurfaceHolder) {
doDraw(c); // Main drawing method - not included in this code snippet
}
}
finally {
// do this in a finally so that if an exception is thrown
// during the above, we don't leave the Surface in an
// inconsistent state
if (c != null) {
mSurfaceHolder.unlockCanvasAndPost(c);
}
}
}
}
}
そして、Thread
表面が破壊されたときに適切に停止します:
public void surfaceDestroyed(SurfaceHolder holder) {
// we have to tell thread to shut down & wait for it to finish, or else
// it might touch the Surface after we return and explode
boolean retry = true;
thread.setRunning(false);
while (retry) {
try {
thread.join();
retry = false;
}
catch (InterruptedException e) {
}
}
}
これまでに通常テストしたデバイス (HTC Desire、Desire HD、および Archos 101 で、記憶が正しければ OS 2.2 と 2.3.3 を搭載) では、上記の問題は発生していません。つまり、ユーザーが をバックアウトしActivity
たり、上で別のActivity
関数が呼び出されたりしたためにサーフェスが破棄された場合、 内のコードは、が返されるために が呼び出されないことsurfaceDestroyed()
を常に保証します。mSurfaceHolder.lockCanvas()
null
ただし、Android 4 / ICS を実行している新しい HTC One X で見つけた違いは、メソッドの呼び出し中surfaceDestroyed()
(つまり、そのメソッド内のコードがまだ実行中) に、描画にからキャンバスThread
が与えられることです。もちろん、これはアプリケーションのクラッシュを引き起こします。私のOne Xでは、これは表面が破壊されるたびに発生します-電話の回転、バックアウトなどによるものです.null
mSurfaceHolder.lockCanvas()
Activity
私はnon- until has really exitedmSurfaceHolder.lockCanvas()
を返す必要があるという印象を受けていたので、これについて混乱しています。確かに、これは Javadoc が言うことです:null
Canvas
surfaceDestroyed()
This is called immediately before a surface is being destroyed. After returning from this call, you should no longer try to access this surface. If you have a rendering thread that directly accesses the surface, you must ensure that thread is no longer touching the Surface before returning from this function.
今のところ私の解決策は、 をチェックすることですnull
。これはうまくいきます:
if(c != null){
doDraw(c); // Main drawing method - not included in this code snippet
}
しかし、Android 4 / ICS で突然これをしなければならない理由はありますか?