【问题标题】:Pause thread when app going to background应用程序进入后台时暂停线程
【发布时间】:2015-02-11 09:26:34
【问题描述】:

我想在应用程序进入后台时暂停线程并在应用程序进入前台时恢复它。但是在返回前台后线程正在运行但 UI 对输入没有反应,并且在一段时间后活动崩溃并且没有错误消息并且应用程序重新启动到主活动。线程运行时不会调用 onResume()。

这是我得到的:

在活动中:

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

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

}

Canvas 扩展了表面视图:

@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) {

            }
        }
    }

引擎扩展线程:

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();
            }
        }

【问题讨论】:

  • this
  • 如果在 UI 不再反应后暂停主线程,它在哪一行?
  • Joan 我已经实现了您的解决方案,但是当我调试它时 onStart() 在第一次启动活动时被调用但当我点击主页按钮时没有任何反应,没有调试器响应没有烤面包没有日志消息。难道是因为我扩展了 ActionBarActivity?

标签: android multithreading


【解决方案1】:

synchronized (mPauseLock) 锁定 mPauseLock

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

当调用 resume 时,下面的代码被锁定,更糟糕的是,它锁定了主线程。

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

所以你只需要删除run();中的同步块

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多