2

这是完整的 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”。现在线程确实结束了,因此,活动在按下后退按钮时关闭。感谢大家提出宝贵的建议。

4

1 回答 1

2

问题是,“ourThread”在加入时永远不会停止。

你必须意识到调用ourThread.join()只是等待线程完成——它不会停止线程。您ourThread可能由于某种原因被挂起。线程转储将显示它正在运行的位置。也许它陷入了一个循环?也许它正在等待网络连接?

如果join()返回成功,根据定义,线程被加入将不再运行。所以线程调用ourThread.join()会一直等到ourThread线程完成。

如果线程不再运行,那么可能还有其他线程在运行,使您的应用程序保持打开状态?线程转储将向您显示还有哪些其他非守护线程。它们需要在您的应用程序停止之前终止。

在查看您的线程代码时,除非RuntimeException抛出 a ,否则我看不到您退出无限循环的任何方法。线程什么时候停止工作?你的意思是做 abreak;而不是 acontinue;吗?

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){
于 2013-06-14T16:02:24.260 回答