为什么我的线程因未捕获的异常而停止?

时间:2012-03-27 21:17:06

标签: java android multithreading

我有以下主题:

class LemonadeMainMenuThread extends Thread {

    private SurfaceHolder mSurfaceHolder;
    private Handler mHandler;
    private Context mContext;
    int mRowId = 0;

    public void setRunning(boolean b) {
        mRun = b;
    }

    public LemonadeMainMenuThread(SurfaceHolder surfaceHolder,
            Context context, Handler handler) {
        mSurfaceHolder = surfaceHolder;
        mHandler = handler;
        mContext = context;
    }

    Resources res = getResources();

    @Override
    public void run() {
        while(1==1)
        {
        if (mRun) {
            try {
                c = mSurfaceHolder.lockCanvas(null);
                synchronized (mSurfaceHolder) {
                    doDraw(c);

                }
            } finally {
                if (c != null) {
                    mSurfaceHolder.unlockCanvasAndPost(c);
                }
            }

        }
        else{try { Thread.sleep(100); } catch (Exception ie) {}}
    }}

}

我在同一个文件中也有以下方法:

public void surfaceCreated(SurfaceHolder arg0) {
    if (thread.getState() == Thread.State.TERMINATED) {
        thread = new LemonadeMainMenuThread(holder, ctx, new Handler() {
            @Override
            public void handleMessage(Message m) {
            }
        });
    }
    thread.setRunning(true);
    thread.start();
}
public LemonadeMainMenuThread setThreadRunning(boolean b) {
    mRun = b;
    if (thread.getState() == Thread.State.TERMINATED) {
        thread = new LemonadeMainMenuThread(holder, ctx, new Handler() {
            @Override
            public void handleMessage(Message m) {
            }
        });
    }
    return thread;
}

在我的逻辑文件中,我有OnPause和OnResume事件,如下所示:

@Override
protected void onPause() {
    mLemonadeMainMenuView.setThreadRunning(false);
    super.onPause();
}

@Override
protected void onResume() {
    mLemonadeMainMenuView.setThreadRunning(true);
    super.onResume();
    b=true;
}

线程正常工作正常,但是当我退出应用程序并返回它时,它会因以下错误而关闭:

FATAL EXCEPTION: Thread-13
03-27 
java.lang.NullPointerException
03-27
at com.example.HelloAndroid.LemonadeMainMenuView$LemonadeMainMenuThread.doDraw(LemonadeMainMenuView.java:106)

at com.example.HelloAndroid.LemonadeMainMenuView$LemonadeMainMenuThread.run(LemonadeMainMenuView.java:72)

这是DoDraw()方法:

    private void doDraw(Canvas canvas) {
        canvas.drawColor(Color.BLACK);
        Paint p = new Paint();
        p.setColor(Color.RED);
        p.setStyle(Style.FILL);
        Paint p3 = new Paint();
        p3.setColor(Color.GREEN);
        p3.setStyle(Style.FILL);
        Paint p2 = new Paint();
        p2.setColor(Color.MAGENTA);
        p2.setStyle(Style.FILL);
        Paint paint = new Paint();
        paint.setColor(Color.TRANSPARENT);
        paint.setStyle(Style.FILL);

        canvas.drawBitmap(mFrog, mx, my, null);
        canvas.drawRect(0, height * 4 / 5, width, height, p);
        int fly=0;
        while(fly<5)
        {
        fly++;
        int xer=flyserd[(fly-1)*2];
        int yer=flyserd[((fly-1)*2)+1];
        canvas.drawCircle(xer, yer, 10, p3);
        }
        fly=0;
        if (clicked) {
            if (stages == 0) {
                stages = (int) (Math.sqrt(Math.pow(MouthX + mx + x + clickx
                        + x / 2, 2)
                        + Math.pow(MouthY + my + y + clicky + y / 2, 2))
                        * height / 40000);
                stages += 1;
            }

            if (systemtime + 10 < System.currentTimeMillis()) {
                systemtime = System.currentTimeMillis();
                if (stage < stages) {
                    stage++;
                    canvas.drawLine(MouthX + mx, MouthY + my,
                            ((clickx - (MouthX + mx)) * stage / stages)
                                    + MouthX + mx,
                            ((clicky - (MouthY + my)) * stage / stages)
                                    + MouthY + my, p2);
                    if (stage == stages) {
                        stage = 0;
                        stages = 0;
                        clicked = false;
                    }
                }
            }
        }
        b = false;
    }

2 个答案:

答案 0 :(得分:2)

遵循堆栈跟踪 - 它会告诉您文件,类,NPE发生的行号。打开IDE中的行号,找到该行,然后查看您找到的哪些引用为nul。在调试器中单步执行。它应该很容易找到 - 比在这里要求更快。

答案 1 :(得分:1)

我认为当您按下按钮

时,您的画布会随着活动一起被销毁

试试这个

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
    if (keyCode == KeyEvent.KEYCODE_BACK) {
        moveTaskToBack(true);
        return true;
    }
    return super.onKeyDown(keyCode, event);
}