http://www.linuxidc.com/Linux/2011-11/48318.htm
症状:游戏过程中,按下Home键返回手机主菜单,再点击游戏图标试图返回游戏的时候屏幕黑的一片!
以前一直没在意只有结束线程在运行游戏,今天觉得改仔细琢磨一下这个问题了!
首先第一件事:打印Logo看看按下Home键后会调用哪些方法,结果如下:
游戏过程中按下Home后:
11-29 20:42:07.090: I/System.out(18835): Activity onPause...
11-29 20:42:14.190: I/System.out(18835): Activity onStop...
11-29 20:42:14.260: I/System.out(18835): SurfaceView surfaceDestroyed...
可见SurfaceView 在返回手机主菜单的时候被销毁了,而我的SurfaceView 主线程是在构造方法里创建的
那么我们返回游戏的时候会调哪些方法呢?接着看Log:
11-29 20:48:06.940: I/System.out(18835): Activity onRestart...
11-29 20:48:06.950: I/System.out(18835): Activity onResume...
11-29 20:48:07.230: I/System.out(18835): SurfaceView surfaceCreated...
11-29 20:48:07.240: I/System.out(18835): SurfaceView surfaceChanged...
surfaceDestroyed 的时候线程已经退出了运行,这时再返回到游戏刷屏的线程就没了,任何绘制方法都没调用,所以你看到的只有黑漆漆的屏幕啦!
明白了运行原理我们就知道改怎么做啦!
首先创建线程放在 surfaceCreated ,并启动线程,
当 surfaceDestroyed 调用的时候,线程已经无效了,我们把线程对象设为null释放他,
然后不管怎么返回线程都会继续运行你的游戏也就不会中断了,来段简单的代码更具表达力度!
package com.game.view;
import Android.content.Context;
import Android.graphics.Canvas;
import Android.graphics.Paint;
import Android.graphics.Paint.Style;
import Android.graphics.Rect;
import Android.view.SurfaceHolder;
import Android.view.SurfaceHolder.Callback;
import Android.view.SurfaceView;
public class TestView extends SurfaceView implements Callback, Runnable{
public static final int GAME_HEART = 1000/30; //每秒刷新30次
public static int screenW, screenH;
private Thread thread;
private SurfaceHolder holder;
private Paint paint;
public TestView(Context context) {
super(context);
// TODO Auto-generated constructor stub
holder = getHolder();
holder.addCallback(this);
paint = new Paint(Paint.ANTI_ALIAS_FLAG);// 无锯齿
paint.setStyle(Style.FILL); //填充样式
paint.setTextSize(16); // 字体大小
}
/**
* 执行游戏逻辑方法
*/
private void update() {
}
/**
* 执行游戏绘制
*/
private Rect rect = new Rect();
private void draw(){
Canvas canvas = holder.lockCanvas();
String text = "天使之翼的示例Demo";
//获取文本宽高
paint.getTextBounds(text, 0, text.length(), rect);
//在屏幕中央位置显示文本
paint.setColor(0xfff000f0); //注意最高两位 ff 代表画笔透明度,不设置的画就是完全透明了,看不到任何效果
canvas.drawText(text,
(screenW - rect.width())/2,
screenH/2 + rect.height()/2,
paint);
holder.unlockCanvasAndPost(canvas);
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
screenW = getWidth();
screenH = getHeight();
thread = new Thread(this);
isRun = true;
thread.start();
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
// TODO Auto-generated method stub
//当屏幕旋转的时候重新获取屏幕宽高
screenW = getWidth();
screenH = getHeight();
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
isRun = false;
thread = null;
}
private boolean isRun; //线程运行标志
private int useTime; //记录每次刷屏使用的时间
@Override
public void run() {
// TODO Auto-generated method stub
long start, end;
while(isRun){
start = System.currentTimeMillis();
update(); // 刷新界面上所有元素
draw(); // 绘制界面元素
end = System.currentTimeMillis();
useTime = (int) (end - start);
if(useTime < GAME_HEART){ //保证每次刷屏时间间隔相同
try {
Thread.sleep(GAME_HEART - useTime);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
本篇文章来源于 Linux公社网站(www.linuxidc.com) 原文链接:http://www.linuxidc.com/Linux/2011-11/48318.htm