这是补充java类(GFXSurface)。在这个类中,定义了第二个类,
public class GFXSurface extends Activity implements OnTouchListener {
AnotherSurface ourSurfaceView;
float x, y;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
ourSurfaceView = new AnotherSurface(this);
ourSurfaceView.setOnTouchListener(this);
x = 0;
y = 0;
setContentView(ourSurfaceView);
}
@Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
ourSurfaceView.ourPause();
}
@Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
ourSurfaceView.ourResume();
}
@Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
x = event.getX();
y = event.getY();
return true;
}
/*------------------------Class within a class-------------------------------*/
public class AnotherSurface extends SurfaceView implements Runnable {
SurfaceHolder ourHolder;
Thread ourThread = null;
boolean isRunning;
public AnotherSurface(Context context) {
// TODO Auto-generated constructor stub
super(context); //not auto-generated; set it up manually
isRunning = false;
ourHolder = getHolder();
}
public void ourPause(){
isRunning = false;
while(true){
try {
ourThread.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
break;
}
ourThread = null;
}
public void ourResume(){
isRunning = true;
ourThread = new Thread(this);
ourThread.start();
}
@Override
public void run() {
// TODO Auto-generated method stub
while(true){
if(!ourHolder.getSurface().isValid())
continue;
Canvas canvas = ourHolder.lockCanvas();
canvas.drawRGB(255, 0, 0);
if(x!=0 && y!=0){
Bitmap ourBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.green_ball);
canvas.drawBitmap(ourBitmap, x-(ourBitmap.getWidth()/2), y-(ourBitmap.getHeight()/2), null);
}
ourHolder.unlockCanvasAndPost(canvas);
}
}
}
}
现在,当我启动活动时,它按需要工作,它会在点击屏幕的位置创建一个位图(以点击为中心)。它给出的问题是,当我按下手机上的后退键时,应用程序停止响应,手机会提供强制关闭应用程序的选项。我认为它必须对“ourThread”线程没有正确连接做一些事情。
知道问题出在哪里?谢谢。
<小时/> 编辑:我确实找到了我错的地方。在while循环中:
while(true){
if(!ourHolder.getSurface().isValid())
continue;
Canvas canvas = ourHolder.lockCanvas();
canvas.drawRGB(255, 0, 0);
if(x!=0 && y!=0){
Bitmap ourBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.green_ball);
canvas.drawBitmap(ourBitmap, x-(ourBitmap.getWidth()/2), y-(ourBitmap.getHeight()/2), null);
}
我刚刚将“true”改为“isRunning”。现在线程结束,因此,按下后退按钮时活动关闭。感谢所有宝贵的建议。
答案 0 :(得分:2)
问题在于,“ourThread”在加入时永远不会停止。
你必须意识到调用ourThread.join()
只有等待才能完成线程 - 它不会停止线程。由于某种原因,您的ourThread
可能会被挂起。线程转储将显示它正在运行的位置。也许它陷入了循环?也许它正在等待网络连接?
如果join()
成功返回,则根据定义,已加入的线程不再运行。所以调用ourThread.join()
的线程将等到ourThread
线程完成。
如果线程不再运行,那么可能还有其他线程正在运行以保持应用程序打开? thread dump会显示other non-daemon threads仍然存在的内容。他们需要在您的申请停止之前终止。
在查看你的线程代码时,除非抛出RuntimeException
,否则我看不到任何退出无限循环的方法。线程什么时候停止工作?您的意思是break;
代替continue;
吗?
while(true){
if(!ourHolder.getSurface().isValid())
continue; // should this be a break?
Canvas canvas = ourHolder.lockCanvas();
canvas.drawRGB(255, 0, 0);
ourHolder.unlockCanvasAndPost(canvas);
}
现在您已添加了更多代码,您需要将isRunning
设为volatile
,以便多个线程可以更新它并查看更新,您应该更改while
循环您的run()
方法是:
private volatile boolean isRunning;
...
while(!isRunning){