定时刷新界面总结

2017-11-29  本文已影响8人  gogoingmonkey

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

先直接看代码

首先使用单例创建对象,在单例里面注册了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

比较上面两种方式

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

上一篇 下一篇

猜你喜欢

热点阅读