如下商品列表秒杀,每一个商品都自带倒计时,如果每个商品都用timer或handler很容易出现卡顿甚至oom的情况

所以如果我只使用一个倒计时来管理这所有的时间实现起来会怎样呢?
what?一个倒计时管理这全部?想想都恐怖......
其实换个思维你会发现,一切如此简单:
我们不需要管这些时间剩多少,只需要管好每隔1秒告诉它:兄弟,过1秒了。至于别人拿这一秒干嘛,那是别人的事。
so,只需要写一个工具类,每隔一段时间回调就行了
/**
* 每个一段时间发送回调的倒计时工具类
* <p>
* 一个handler管理所有的倒计时,防止创建过多的handler
*/
public class DaoJiShiUtils {
private final HashSet<OnDaoJiShiListener> mSetListeners = new HashSet<>();
private final int mHandlerTime;
@Nullable
private final Activity mActivity;
@SuppressLint("HandlerLeak")//本代码不会出现内存泄漏
private final Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
if (mSetListeners.size() == 0 || (mActivity != null && mActivity.isFinishing())) {
return;
}
Object[] listeners = mSetListeners.toArray();
for (Object listener : listeners) {
//noinspection SuspiciousMethodCalls 做这一步判断是因为遍历过程中可能会被删掉
if (mSetListeners.contains(listener)) {
((OnDaoJiShiListener) listener).onZeroOneSecond();
}
}
sendEmptyMessageDelayed(1, mHandlerTime);
}
};
/**
* @param activity 防止出现内存泄漏,此处强制要求传入当前Activity。不传也可以,但必须自己手动关掉{@link #stopAll}
* @param intervals 发送间隔毫秒值,比如100表示0.1秒发一次、1000表示1秒发一次
*/
@MainThread
public DaoJiShiUtils(@Nullable Activity activity, int intervals) {
mActivity = activity;
mHandlerTime = intervals;
}
/**
* 添加倒计时回调
*/
@MainThread
public void addTimeListener(@NonNull OnDaoJiShiListener listener) {
if (mSetListeners.size() == 0) {
mHandler.removeMessages(1);
mHandler.sendEmptyMessageDelayed(1, mHandlerTime);
}
mSetListeners.add(listener);
}
/**
* 删除倒计时
*/
@MainThread
public boolean removeTimeListener(@NonNull OnDaoJiShiListener listener) {
return mSetListeners.remove(listener);
}
/**
* 如果没传Activity,则需要手动停止
*/
@MainThread
public void stopAll() {
mSetListeners.clear();
mHandler.removeCallbacksAndMessages(null);
}
/**
* 监听
*/
public interface OnDaoJiShiListener {
/**
* 每隔一段时间回调一次
*/
void onZeroOneSecond();
}
}
然后只要在Activity里new一个,Adapter都使用它即可
mDjs = new DaoJiShiUtils(this, 10);
//...
//adapter的适当位置
mDjs.addTimeListener(mTimeListener);
核心逻辑虽然少,但要想真正使用需要不少代码配合,下方有demo,可自行参考使用
常见问题1:倒计时回调特别多的时候(满屏都是),导致重绘次数太多引起卡顿
由于倒计时都是固定长度固定格式的,所以我们只需要自定义一个倒计时的view(见demo的MyDaoJiShiView),数据加载好之后就不需要再requestLayout了,直接拦截掉就行
常见问题2:demo在滑动的时候似乎也有点卡
这是因为比较懒,直接用了RecyclerView的notifyDataSetChanged,并且demo的倒计时到时间的特别多,也会导致刷新次数过多而卡顿,并不是倒计时引起的卡顿,这个可以自行优化,就不多说了。
demo或直接使用地址:GitHub - weimingjue/LifeCountdownTimer: 专为大量倒计时定制的工具类,简洁而又强大(com.github.weimingjue:CountdownUtil)
介绍了一种使用单一倒计时工具类管理多个商品秒杀倒计时的方法,避免了因大量独立计时器造成的卡顿和内存溢出问题。通过自定义View减少重绘次数,优化了性能。

7366

被折叠的 条评论
为什么被折叠?



