web-dev-qa-db-ja.com

AndroidアプリケーションでのWaitingInMainSignalCatcherLoopエラー

Androidアプリケーションが33ミリ秒ごとに画面を更新し、座標のペアに長方形を表示します。カスタムビューのコードは次のとおりです。

import Android.content.Context;
import Android.graphics.Bitmap;
import Android.graphics.BitmapFactory;
import Android.graphics.Canvas;
import Android.os.Handler;
import Android.util.AttributeSet;
import Android.view.SurfaceHolder;
import Android.view.SurfaceView;

public class OurView extends SurfaceView implements SurfaceHolder.Callback {

    private SurfaceHolder holder;
    private Handler handler = new Handler();
    private Bitmap testimg;
    private int xCoord = 500;
    private int yCoord = 500;
    boolean running = false;
    int xPos;
    int yPos;

    public OurView(Context context) {
        super(context);
        init();
    }

    public OurView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public OurView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init();
    }

    private void init() {
        holder = getHolder();
        holder.addCallback(this);
        testimg = BitmapFactory.decodeResource(getResources(),R.drawable.testimg);
    }

    void moveImage(int xChange, int yChange) {
        this.xCoord = this.xCoord + xChange;
        this.yCoord = this.yCoord + yChange;
    }

    void doDraw(Canvas canvas) {
        xPos = this.xCoord + (testimg.getWidth()/2);
        yPos = this.yCoord + (testimg.getHeight()/2);
        canvas.drawARGB(255, 55, 255, 255);
        canvas.drawBitmap(testimg, xPos, yPos, null);
    }

    @Override
    public void surfaceCreated(final SurfaceHolder holder) {
        running = true;
        while(running){

            handler.postDelayed(new Runnable() {
                public void run() {

                    Canvas canvas = getHolder().lockCanvas();

                    if(canvas != null){
                        synchronized (getHolder()) {
                            doDraw(canvas);
                        }
                        holder.unlockCanvasAndPost(canvas);
                    }

                }
            }, 33);

        }
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {}


    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {}

}

以前は描画を処理する別のスレッドを使用していましたが、そのため、スレッド間で値が異なる変数で問題が発生しました。このプログラムを実行すると、次のエラーが発生します。

04-20 10:54:35.577    1925-1931/com.thatoneprogrammerkid.gameminimum I/art﹕ Thread[2,tid=1931,WaitingInMainSignalCatcherLoop,Thread*=0xae668400,peer=0x12c00080,"Signal Catcher"]: reacting to signal 3
04-20 10:54:35.577    1925-1931/com.thatoneprogrammerkid.gameminimum I/art﹕ [ 04-20 10:54:35.627  1925: 1931 W/art      ]
14
WD40

これはエラーではなく、VMアプリにシグナル3(SIGQUIT)が送信されたことを通知します。最も可能性の高い原因は、アプリが応答せず、システムがANR処理を実行していることです- -SIGQUITはVMにスタックトレースをダンプさせます。

LogcatでANRの苦情が見られますか?

コードを見ると、UIスレッドで実行されるsurfaceCreated()でループしています。つまり、アプリはシステムからのメッセージを処理できません(またはビューに描画したり、ユーザー入力を受け取ったりできません)。以前と同じように別のスレッドを使用するか(ただし、同期を改善する)、またはsurfaceCreated()からループを削除して、描画ハンドラに毎回postDelayed()を再発行させることができます。実行します。

12
fadden