package com.sandro.util; import java.util.HashSet; import java.util.Iterator; import android.os.Handler; import android.os.Message; import android.util.Log; /** * * @ClassName: CartonEngine * @Description:用于动画定时回调 * @author: Sandro * @date: 2012-10-25 下午02:44:02 * */ public class CartonEngine { /** * 原子周期为25ms */ public static final int DEFAULT_CIRCLE = 25; private CartonHandler mHandler; private Engine engine; /** * 时间线,用于计算下一周期的时间,单位 : 周期 */ private long circleLine; /** * 标识当前引擎是否正在工作中 */ private boolean isRunning = false; private HashSet<CartonElement> cartonElements; /** * @param handler */ public CartonEngine(){ engine = new Engine(); mHandler = new CartonHandler(); cartonElements = new HashSet<CartonElement>(); } private void start(){ engine.start(); } /** * 通过handler发送移除回调接口请求 * @param listener */ public void requestRemove(CartonCallBackLisener listener){ mHandler.sendRemoveListenerRequest(listener); } /** * 动画结束,调用该方法动画引擎将不再回调 * @param listener */ private void remove(CartonCallBackLisener listener){ if(listener==null){ Log.w("CartonEngine", "[public void remove] : listener is null" ); return; } synchronized (cartonElements){ CartonElement ele = null; for(CartonElement e : this.cartonElements){ if(listener.equals(e.listener)){ ele = e; break; } } if(ele!=null){ cartonElements.remove(ele); } } } private void plugInListener(CartonCallBackLisener listener) { if (listener == null) { Log.w("CartonEngine", "[public void addListener] : listener is null"); return; } synchronized (cartonElements) { boolean getSame = false; for (CartonElement ele : this.cartonElements) { if (listener.equals(ele.listener)) { getSame = true; break; } } if (!getSame) { this.cartonElements.add(new CartonElement(listener)); } } if (!isRunning) { start(); } } public void addListener(CartonCallBackLisener listener){ if(listener!=null){ mHandler.sendAddListenerRequest(listener); } } public void destory(){ this.mHandler.removeCallbacks(this.engine); this.removeAll(); } private void removeAll(){ synchronized (cartonElements){ for(CartonElement ele : this.cartonElements){ ele.clear(); } cartonElements.clear(); } } private class Engine implements Runnable { private void start() { long firstCircle = firstCallBackCircle(); if(firstCircle > 0){ long postDaly = firstCircle - circleLine; Log.i("CartonEngine.Engine", "[private void start()] circleLine : " + circleLine + " ,firstCircle : " + firstCircle); mHandler.postDelayed(this, postDaly * DEFAULT_CIRCLE); circleLine = firstCircle; Log.i("CartonEngine.Engine", "[private void start()] circleLine : " + circleLine + ", postDaly : " + postDaly ); isRunning = true; }else{ isRunning = false; } } @Override public void run() { // long t = System.currentTimeMillis(); callBack(); // Log.i("CartonEngine.Engine", "[public void run()] circleLine : " + circleLine // + ",use time :" + (System.currentTimeMillis() - t)); long nextCircle = firstCallBackCircle(); long postDaly = nextCircle - circleLine; // Log.i("CartonEngine.Engine", "[public void run()] nextCircle : " + nextCircle // + ",postDaly : " + postDaly); if(nextCircle > 0){ mHandler.postDelayed(this, postDaly * DEFAULT_CIRCLE); circleLine = nextCircle; isRunning = true; }else{ isRunning = false; } } }; private void callBack() { synchronized (cartonElements) { Iterator<CartonElement> iterator = cartonElements.iterator(); while (iterator.hasNext()) { CartonElement ele = iterator.next(); if (ele.listener != null && !ele.listener.isPause()) { // Log.i("CartonEngine", "[public void callBack()] ele : " + // ele.listener.getCircleMultiple() // + " ,ele.selfTimeLine : " + ele.selfTimeLine // + " ,this.circleLine : " + this.circleLine); if (ele.selfTimeLine == this.circleLine) { ele.listener.onTime(); ele.generateNextTime(); } } // Log.i("CartonEngine", "[public void callBack()] ele : " + // ele.listener.getCircleMultiple() // + " ,nextTime : " + ele.selfTimeLine); } } } /** * 计算第一次应该回调的周期 * @return */ private long firstCallBackCircle(){ long circle = 0; synchronized (cartonElements){ for(CartonElement ele:cartonElements){ if(circle == 0){ circle = ele.selfTimeLine; }else{ if(circle > ele.selfTimeLine){ circle = ele.selfTimeLine; } } } } return circle; } /** * * @ClassName: CartonCallBackLisener * @Description:回调接口 * @author: Sandro * @date: 2012-10-25 下午04:57:11 * */ public interface CartonCallBackLisener{ /** * 时钟周期回调 */ public void onTime(); /** * 动画的周期倍数 * 1 :25ms回调,2:50ms回调.... * @return */ public int getCircleMultiple(); /** * 动画是否暂停 * @return true : 动画暂停,在下一个周期不会回调 * false : 在下一个周期将继续回调 */ public boolean isPause(); } private class CartonElement{ private CartonCallBackLisener listener; private long selfTimeLine; private CartonElement(CartonCallBackLisener listener) { this.listener = listener; selfTimeLine = circleLine; generateNextTime(); } private void clear() { this.listener = null; selfTimeLine = 0; } private void generateNextTime(){ selfTimeLine += listener.getCircleMultiple(); } } private class CartonHandler extends Handler{ /** * 注销回调请求 */ private final static int REMOVE_CARTON_LISTENER = 1; private final static int ADD_CARTON_LISTENER = 2; @Override public void handleMessage(Message msg) { switch (msg.what) { case REMOVE_CARTON_LISTENER: CartonCallBackLisener listener = (CartonCallBackLisener)msg.obj; remove(listener); break; case ADD_CARTON_LISTENER: if(msg.obj!=null){ listener = (CartonCallBackLisener)msg.obj; plugInListener(listener); } break; } } /** * 通过handler发送回调对象注销请求 * @param listener */ private void sendRemoveListenerRequest(CartonCallBackLisener listener){ if(listener==null){ return; } Message msg = new Message(); msg.what = REMOVE_CARTON_LISTENER; msg.obj = listener; sendMessage(msg); } private void sendAddListenerRequest(CartonCallBackLisener listener){ Message msg = new Message(); msg.what = ADD_CARTON_LISTENER; msg.obj = listener; sendMessage(msg); } } }