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では、これは表面が破壊されるたびに発生します-電話の回転、バックアウトなどによるものです.nullmSurfaceHolder.lockCanvas()Activity
私はnon- until has really exitedmSurfaceHolder.lockCanvas()を返す必要があるという印象を受けていたので、これについて混乱しています。確かに、これは Javadoc が言うことです:null CanvassurfaceDestroyed()
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 で突然これをしなければならない理由はありますか?