在onResume和onPause之间做功能的一些思考

转载请注明出处:http://blog.csdn.net/kester_/article/details/52464066

发现问题

有时候需要在onResume中做一些功能,但是在手机锁屏或切换出去时
就要停止该功能,这时会一般会选择在onPause中做停止操作,但是这个功能如果是会对UI元素进行操作,可能会导致CalledFromWrongThreadException。


研究问题

直接上代码

Thread mThread = null;
@Override
protected void onResume() {
    super.onResume();
    dealAnimation(true);
}

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

private void dealAnimation(boolean isStart) {
    if (isStart) {
        mThread = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(500);
                } catch (Exception e){}
                // doAnim();
            }
        });
        mThread.start();
    } else {
        if (mThread != null && !mThread.isInterrupted()) {
            mThread.interrupt();
            mThread = null;
        }
    }
}

我把所有操作放在一个单独的线程里,在onResume里调用起来,由于需要延时500毫秒,万一在界面切换走时仍然被执行,肯定会出问题,所以在onPause里进行了杀线程操作。
本地测试没问题,但是在版本放出去之后发现,部分机型上出现了CalledFromWrongThreadException,在doAnima()方法里进行了UI元素操作,异步线程操作UI元素,当然会出问题了。
为了操作UI元素,可以使用Handler将事件post到主线程,这样一来解决了CalledFromWrongThreadException,但是万一Activity切换出去了应该怎么停止该功能呢?
那,应该如何完成在onResume里开始,onPause后又不执行呢?
其实可以换个思路,不一定要onPause里结束,只要onPause之后不执行就ok了,可以在执行功能的时候判断是否是当前Activity,如果是当前Activity才执行,这样的话就可以使用Handler将事件post到主线程而不需要担心无法结束该功能了。


解决问题

换个思路后代码如下:

boolean mIsCurrentActivity = false;
    @Override
    protected void onResume() {
        super.onResume();
        mIsCurrentActivity = true;
        dealAnimation();
    }

    @Override
    protected void onPause() {
        super.onPause();
        mIsCurrentActivity = false;
    }

    private void dealAnimation() {
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                if (!mIsCurrentActivity) {
                    return;
                }
                // doAnim();
            }
        }, 500);
    }

这样,既将事件post到主线程了,又保证了Activity不在前台时不执行该任务。


概括结论

第一种写法将功能放到异步线程,在onPause里结束线程,虽然防止了Activity切换出去时仍然执行该任务,但是由于该任务操作了UI元素而会抛出异常;第二种写法将事件通过Handler来post到主线程,同时在执行之前判断了Activity是否在当前,既防止了Activity切换出去时仍然执行该任务,又防止了异步线程操作UI元素导致的崩溃,问题搞定。

你可能感兴趣的:(课题研究)