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

来源:互联网 发布:擦窗机器人 知乎 编辑:程序博客网 时间:2024/05/17 02:48

发现问题

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


研究问题

直接上代码

Thread mThread = null;@Overrideprotected void onResume() {    super.onResume();    dealAnimation(true);}@Overrideprotected 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元素导致的崩溃,问题搞定。

0 0