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

定时刷新界面总结

作者: 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

比较上面两种方式

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

相关文章

  • 定时刷新界面总结

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

  • MFC:OnTimer与QT:QTimer

    一 MFC中定时器的使用 1.1、使用场景 定时读写数据,或者定时刷新界面,更新数据和状态。 1.2、使用 (1)...

  • Runloop底层整理

    定义 运行循环 应用范畴 定时器, PerformSelectorGCD事件相应,手势识别,界面刷新网络强求自动释...

  • HttpServletResponse定时刷新

    一,实现网页的定时刷新并跳转 二,实现当前页面定时自动刷新

  • APP产品何时刷新内容?

    1、启动请求刷新 2、手动下拉刷新 2、定时推送刷新

  • iOS - CADisplayLink与NSTimer

    一、CADisplayLink简介 CADisplayLink 是一个定时器对象可以让你的应用以与显示器的刷新界面...

  • 定时器Timer

    定时器用于实现定时操作,如: 每三分钟保存一次 每500毫秒闪烁一次 每1秒刷新一次界面 新建Timer (1) ...

  • iOS双波浪动画解析

    场景需求分析,如图 1.自定义View 2.利用CADisplayLink定时器,每秒60次刷新界面 3.在Vie...

  • 深入学习iOS定时器

    定时器,用来延迟或重复执行某些方法,例如:网络定时刷新,UI间隔刷新,动画效果......iOS中的定时器大致分为...

  • 简单的定时刷新和周期刷新的定时器

    安卓使用Alarm实现一个简单的定时刷新和周期刷新的定时器 alarmManger的获得AlarmManger a...

网友评论

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

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