美文网首页
定时刷新界面总结

定时刷新界面总结

作者: gogoingmonkey | 来源:发表于2017-11-29 17:19 被阅读8次

    最近一个版本的迭代有个需求就是黄金的金价需要实时刷新,最终确定用下面的方案,顺便总结了一下其他思路。

    先直接看代码

    首先使用单例创建对象,在单例里面注册了Evenbus ,这种写法不推荐,写了一个请求网络的方法,这个方法是在后面handler 中先去调用检查是否有监听者,如果有就使用handler 发送 还定义了添加移除监听的方式:

    public class GoldPriceProvider implements IGoldPriceProvider {
        private static final int ACTION_GOLD_REQUEST = 0x101010;
        private static List<OnGoldPriceFreshListener> sSubscriber = new CopyOnWriteArrayList();
        private  Handler mHandler = new GoldFreshHandler();
        /**
         * 黄金刷新频率
         */
        private static  int GOLD_UPDATE_DURATION = 5 * 1000;
        private static volatile GoldPriceProvider sGoldPriceProvider;
        /**
         * 默认黄金价格
         */
        private GoldPrice mGoldPrice = new GoldPrice();
    
        private GoldPriceProvider(){}
        public static GoldPriceProvider getSingleton() {
            if (sGoldPriceProvider == null) {
                synchronized (GoldPriceProvider.class) {
                    if (sGoldPriceProvider == null) {
                        sGoldPriceProvider = new GoldPriceProvider();
                        EventBus.getDefault().register(sGoldPriceProvider);
                    }
                }
            }
            return sGoldPriceProvider;
        }
    
        public GoldPriceProvider request(){
            GoldMessageEvent.GoldPriceEvent event = new GoldMessageEvent.GoldPriceEvent();
            GoldApi.fetchGoldPrice(new OnInnerRequestListener(event));
            return this;
        }
    
        @Subscribe(threadMode = ThreadMode.MAIN)
        public void onGoldPriceFetchedDone(GoldMessageEvent.GoldPriceEvent event){
            int state = event.state;
            Object result = event.result;
            String errorTip = CommonUtils.getResponeErrorTip(BaseApplicationProxy.getApplicationContext(), state, result);
            if (!TextUtils.isEmpty(errorTip)) {
                return;
            }
            Response<GoldPrice> response = (Response<GoldPrice>) result;
            GoldPrice price = response.data;
            if(price != null){
                this.mGoldPrice = price;
                //如果接受黄金价格消息者不为零,则广播消息
                if(checkActiveListener() >0) {
                    GOLD_UPDATE_DURATION = price.goldPriceRefreshInterval;
                    this.dispatch(price);
                }
            }
        }
    
        /**
         * 注册黄金价格变动侦听接口
         *
         * @param listener
         */
        public void addListener(OnGoldPriceFreshListener listener) {
            Iterator<OnGoldPriceFreshListener> it = sSubscriber.iterator();
            while (it.hasNext()) {
                OnGoldPriceFreshListener reference= it.next();
                if (listener == reference) {
                    return;
                }
            }
            sSubscriber.add(listener);
            mHandler.removeMessages(ACTION_GOLD_REQUEST);
            mHandler.sendEmptyMessage(ACTION_GOLD_REQUEST);
        }
    
        private int checkActiveListener(){
            return sSubscriber.size();
        }
    
        /**
         * 分发时时金价,并且删除空订阅引用回调接口;
         * @param price
         */
        public void dispatch(GoldPrice price){
            Iterator<OnGoldPriceFreshListener> it = sSubscriber.iterator();
            while (it.hasNext()) {
                OnGoldPriceFreshListener reference= it.next();
                if (reference != null) {
                    reference.onGoldPriceRefreshed(price);
                }
            }
        }
    
        /**
         * 移除黄金价格变动侦听接口
         *
         * @param listener
         */
        public void removeListener(OnGoldPriceFreshListener listener) {
            Iterator<OnGoldPriceFreshListener> it = sSubscriber.iterator();
            while (it.hasNext()) {
                OnGoldPriceFreshListener saved = it.next();
                if (listener == saved) {
                    sSubscriber.remove(saved);
                }
            }
        }
    
        @Override
        public GoldPrice getLatestGoldPrice() {
            return mGoldPrice;
        }
    
        public  class GoldFreshHandler extends Handler{
            @Override
            public void handleMessage(Message msg) {
                super.handleMessage(msg);
                request();
                if(checkActiveListener()>0) {
                    mHandler.sendEmptyMessageDelayed(ACTION_GOLD_REQUEST, GOLD_UPDATE_DURATION);
                }
            }
        }
    }
    
    

    上面的代码是有问题的,具体的问题就是使用了弱引用,这个在内存不足的时候,会把这个对象回收了,我们的监听就被干掉了,干掉了,实时刷新金价就不生效了。
    更改为:

     private static List<OnGoldPriceFreshListener> sSubscriber = new CopyOnWriteArrayList();
    

    然后把正常调d代码也贴出:

        @Override
        protected void onResume() {
            super.onResume();
            GoldPriceProvider.getSingleton().addListener(this);
        }
    
        @Override
        protected void onPause() {
            super.onPause();
            GoldPriceProvider.getSingleton().removeListener(this);
        }
    
    
        @Override
        public void onGoldPriceRefreshed(IGoldPriceProvider.GoldPrice price) {
            if(price == null ){
                return;
            }
            this.mCurrentValueServer.setText(String.valueOf(price.goldPrice));
        }
    

    定时刷新方式1:

    public class MainActivity extends Activity {
        private TextView msg;
        final Handler handler = new Handler() {
            public void handleMessage(Message msg) {
                switch (msg.what) {
                case 1:
                    update();
                    break;
                }
                super.handleMessage(msg);
            }
            void update() {
                //刷新msg的内容
            }
        };
        Timer timer = new Timer();
        TimerTask task = new TimerTask() {
            public void run() {
                Message message = new Message();
                message.what = 1;
                handler.sendMessage(message);
            }
        };
        /** Called when the activity is first created. */
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
            msg = (TextView) findViewById(R.id.txtMsg);
            msg.setText("你好啊!");
            timer.schedule(task, 1000 * 40, 1000 * 30); //启动timer
        }
        @Override
        protected void onDestroy() {
            if (timer != null) {// 停止timer
                timer.cancel();
                timer = null;
            }
            super.onDestroy();
        }
    }
    

    定时刷新方式2

    1
    public class MainActivity extends Activity {
    2
        private TextView msg;
    3
        private Handler handler = new Handler();
    4
        private Runnable runnable = new Runnable() {
    5
            public void run() {
    6
                this.update();
    7
                handler.postDelayed(this, 1000 * 120);// 间隔120秒
    8
            }
    9
            void update() {
    10
                //刷新msg的内容
    11
            }
    12
        }; 
    13
        /** Called when the activity is first created. */
    14
        @Override
    15
        public void onCreate(Bundle savedInstanceState) {
    16
            super.onCreate(savedInstanceState);
    17
            setContentView(R.layout.main);
    18
            msg = (TextView) findViewById(R.id.txtMsg);
    19
            msg.setText("你好啊!");
    20javascript:void(null)
            handler.postDelayed(runnable, 1000 * 60);
    21
        }
    22
        @Override
    23
        protected void onDestroy() {
    24
            handler.removeCallbacks(runnable); //停止刷新
    25
            super.onDestroy();
    26
        }
    27
    }
    28
    29
    

    比较上面两种方式

    第一种方式还适用于消息通知的方式实现更新,第二种方式通常是主动去检查是否需要刷新。对于定时刷新这种使用第二种方式更好

    相关文章

      网友评论

          本文标题:定时刷新界面总结

          本文链接:https://www.haomeiwen.com/subject/xplpbxtx.html