miskohut
miskohut

Reputation: 1017

Pause thread when app going to background

I want to pause thread when app goes to background and resume it when app comes to foreground. But after return to foreground thread is running but UI doesn't react on input, and after a while activity crash with no error message and app is restarted to main activity. onResume() is not called when thread is running.

Here's what i've got:

in Activity:

 @Override
public void onPause() {
    super.onPause();
    if (running) {
        canvas.getEngine().onPause();
    }
}

@Override
public void onResume() {
    super.onResume();
    if (running) {
        canvas.getEngine().onResume();
    }

}

Canvas extends surface view:

@Override
    public void surfaceCreated(SurfaceHolder surfaceHolder) {
        if (!engine.isRunning()) {
            engine.setRunning(true);
            engine.start();
        }
    }

    @Override
    public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {

    }

    @Override
    public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
        boolean retry = true;

        while (retry) {
            try {
                engine.join();
                retry = false;
            }
            catch (InterruptedException e) {

            }
        }
    }

and engine extends thread:

private boolean mPaused;
private Object mPauseLock;
        @Override
            public void run() {

        //bla bla

        synchronized (mPauseLock) {
                        while (mPaused) {
                            try {
                                mPauseLock.wait();
                            } catch (InterruptedException e) {
                            }
                        }
                    }
                }

      public void onPause() {
            synchronized (mPauseLock) {
                mPaused = true;
            }
        }

        /**
         * Call this on resume.
         */
        public void onResume() {
            synchronized (mPauseLock) {
                mPaused = false;
                mPauseLock.notifyAll();
            }
        }

Upvotes: 2

Views: 904

Answers (1)

Joe Lin
Joe Lin

Reputation: 56

synchronized (mPauseLock) locks mPauseLock in

synchronized (mPauseLock) {
                while (mPaused) {
                    try {
                        mPauseLock.wait();
                    } catch (InterruptedException e) {
                    }
                }
            }
        }

When resume is called, the code below is locked, and worse still, it locks the main thread.

synchronized (mPauseLock) {
    mPaused = false;
    mPauseLock.notifyAll();
}

so you just need to remove the synchronized block in run();

Upvotes: 1

Related Questions