如何使用 onRestart() 取消暂停/重新启动 Android 活动中的线程



对于 Android 活动,如何在 onStop() 上停止或暂停线程,然后在onRestart()上重新启动或取消暂停该线程?当我在手机上启动另一个活动时,看起来onStop()正确地停止了我的线程,但是当我尝试重新启动我的活动时,onRestart()无法按预期工作,线程不再运行,即我的视图不再刷新并且倒计时被冻结。(旋转我的手机似乎重新启动线程,即视图恢复刷新并且倒计时处于活动状态。

另外,onStop()停止线程更好,还是应该只暂停它?

public class MyActivity extends Activity {
    private static final int SLEEP_TIME = 500;  
    private RefreshingThread refreshingThread = new RefreshingThread();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        refreshingThread.start();
    }
    @Override
    protected void onStop(){
        super.onStop();
        refreshingThread.pause();
    }
    @Override
    protected void onRestart() {
        super.onRestart();
        refreshingThread.unpause();
    }
    private void updateViews() {
    // code to update my Views, including refreshing a countdown        
    }
    class RefreshingThread extends Thread {
        private volatile boolean isPaused = false;
        @Override
        public void run() {
            try {
                while (!isInterrupted() && !isPaused) {
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                             updateViews();
                        }
                    });
                    Thread.sleep(SLEEP_TIME);
                }
            } catch (InterruptedException e) {
                Log.w("MyActivity", "Caught InterruptedException", e);
            }
        }
        public void pause() {
            isPaused = true;
        }
        public void unpause() {
            isPaused = false;
        }
    }
}

首先,建议通过从服务器推送新数据而不是拉取数据来完成刷新数据 - 这将有助于节省电池、带宽和提高效率。 您可以使用 GCM 推送数据,例如 check: http://www.doubleencore.com/2013/09/push-don't-poll-how-to-use-gcm-to-update-app-data/

如果您仍然喜欢每 X 秒 (SLEEP_TIME) 提取一次数据,我建议您使用计时器,它可以计划为每 X 秒运行一次 TimerTask。 然后,您可以从暂停/恢复取消/重新启动它。例:

public class RefreshManager {
    private static Timer timer = null;
    private RefreshTimerTask refreshTask;
    public void onResume() {
        this.start(INIT_DELAY_TIME);
    }
    public void onPause() {
        this.stop();
    }
    private void start(long delay) {
        stop(); // stop any older timer instance if exist.
        timer = new Timer();
        refreshTask = new RefreshTimerTask();
        timer.schedule(refreshTask, delay, SLEEP_TIME);
    }
    private void stop() {
        if (timer != null) {
            timer.cancel();
            refreshTask = null;
            timer = null;
        }
    }
    private class RefreshTimerTask extends TimerTask {
        @Override
        public void run() {
            updateViews();
        }
    }
}

您应该创建一个 RefreshManager 实例,并在 onResume 上调用它,并在 Pause/onResume 上调用该活动。

更改此方法:

@Override
protected void onRestart() {
    super.onRestart();
    refreshingThread.unpause();
}

自:

@Override
protected void onStart() {
    super.onStart();
    refreshingThread.start();   <-- remove from onCreate();
}

这样,您将始终在活动启动(或重新启动)时启动线程,并在活动停止时停止线程。

我让它工作了。我将线程的 pause() 方法重命名为 shouldStop()。我每次在onStart()中创建一个新线程,同时每次在onStop()中调用我的线程的shouldStop()方法。

private RefreshingThread refreshingThread = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
}
@Override
protected void onStart(){
    super.onStart();
    refreshingThread = new RefreshingThread();
    refreshingThread.start();       
}  
@Override
protected void onStop(){
    super.onStop();
    refreshingThread.shouldStop(); 
}

最新更新