2

これは完全な Java クラス (GFXSurface) です。このクラス内で、2 番目のクラスが定義され、

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がスローされない限り、無限ループを終了する方法がわかりません。スレッドが機能しなくなるのはいつですか? break;a の代わりに aを実行するつもりでした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あります。volatilewhilerun()

private volatile boolean isRunning;
...
while(!isRunning){
于 2013-06-14T16:02:24.260 に答える