use*_*644 5 multithreading android exit surfaceview
我有一个surfaceview和一个gameThread类.gameThread不断更新和绘制SurfaceView类.
现在,当我退出应用程序时(通过按下主页或后退按钮),我收到一条消息,表明应用程序已关闭.那是因为GameThread仍然试图在擦除的surfaceview上画画......
那么如何在不获得此强制关闭通知的情况下正确结束应用程序?我希望GameThread类在按下后退按钮时停止.当按下主页并在后台运行时它应该暂停.当重新进入仍然运行的游戏时,它应该恢复....
有任何想法吗?
这是我的GameThread类:
public class GameThread extends Thread{
private GameView view;
public boolean isRunning = false;
public GameThread(GameView view) {
this.view = view;
}
public void setRunning(boolean setRunning) {
isRunning = setRunning;
}
public void run() {
while(isRunning) {
Canvas c = null;
view.update();
try {
c = view.getHolder().lockCanvas();
synchronized (view.getHolder()) {
view.draw(c);
}
}finally {
if(c != null) {
view.getHolder().unlockCanvasAndPost(c);
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
它不断更新我的GameView类:
公共类GameView扩展了SurfaceView {
private GameThread gameThread;
public GameView(Context context, Activity activity) {
super(context);
gameThread = new GameThread(this);
init();
holder = getHolder();
holder.addCallback(new SurfaceHolder.Callback() {
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
gameThread.setRunning(true);
gameThread.start();
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
}
});
}
public void init() {
}
public void update() {
}
public void draw(Canvas canvas) {
super.draw(canvas);
}
}
Run Code Online (Sandbox Code Playgroud)
当按下home时,我的logcat显示了这个:
02-24 18:24:59.336: E/SurfaceHolder(839): Exception locking surface
02-24 18:24:59.336: E/SurfaceHolder(839): java.lang.IllegalStateException: Surface has already been released.
02-24 18:24:59.336: E/SurfaceHolder(839): at android.view.Surface.checkNotReleasedLocked(Surface.java:437)
02-24 18:24:59.336: E/SurfaceHolder(839): at android.view.Surface.lockCanvas(Surface.java:245)
02-24 18:24:59.336: E/SurfaceHolder(839): at android.view.SurfaceView$4.internalLockCanvas(SurfaceView.java:872)
Run Code Online (Sandbox Code Playgroud)
主要活动:
public class MainActivity extends Activity {
private RelativeLayout relativeLayout;
private GameView gameView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
gameView = new GameView(this, this);
setContentView(R.layout.activity_main);
relativeLayout = (RelativeLayout)findViewById(R.id.mainView);
relativeLayout.addView(gameView);
}
@Override
public void onBackPressed() {
// TODO Auto-generated method stub
super.onBackPressed();
gameView.onBackPressed();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
Run Code Online (Sandbox Code Playgroud)
底层在应用程序生命周期之间和过程中Surface被SurfaceView破坏。向 中的渲染器线程发送消息,并等待线程关闭。onPause()onDestroy()onPause()
有关示例,请参阅Grafika中的“硬件缩放器练习器”活动。SurfaceHolder它在的回调中启动渲染线程surfaceCreated()。
更新:在 中启动线程surfaceCreated()并在 中停止它感觉很奇怪onPause(),因此经过一番重新整理之后,HardwareScalerActivity 现在停止了 中的线程surfaceDestroyed()。(SurfaceView 文档有点含糊——它说 Surface 在“surfaceCreated()和surfaceDestroyed()”之间有效——但查看 SurfaceView 实现,这似乎是预期的用法。)
更新2:在发现代码处理不好的情况后,我又更新了代码。现在源码里有60行的大评论,这也可以在我对类似问题的回答中看到。
更新 3:大型评论变成了架构文档附录。Grafika 的“硬件缩放器练习器”活动演示了方法#2,而“来自相机的纹理”则演示了方法#1。
| 归档时间: |
|
| 查看次数: |
3050 次 |
| 最近记录: |