AndroidUtilCode
AndroidUtilCode copied to clipboard
ThreadUtils内存泄露
描述 Bug
调用ThreadUtils的executeAtFixedRate相关方法取消后会内存泄露,虽然task cancel了,但是timerTask没有cancel。
- AndroidUtilCode 的版本:
- 出现 Bug 的设备型号: Honor 20
- 设备的 Android 版本: API 30
相关代码
ThreadUtils.executeByCachedAtFixRate(task, 1, 1, TimeUnit.SECONDS);
ThreadUtils.cancel(task);
异常堆栈
put the stack of crash here
截图
如果有的话请添加屏幕截图以帮助解释问题。

兄弟解决了吗,我也碰到了
private static <T> void execute(final ExecutorService pool, final Task<T> task,
long delay, final long period, final TimeUnit unit) {
synchronized (TASK_POOL_MAP) {
if (TASK_POOL_MAP.get(task) != null) {
Log.e("ThreadUtils", "Task can only be executed once.");
return;
}
TASK_POOL_MAP.put(task, pool);
}
if (period == 0) {
if (delay == 0) {
pool.execute(task);
} else {
TimerTask timerTask = new TimerTask() {
@Override
public void run() {
if (task.isCanceled()) {
cancel();
return;
}
pool.execute(task);
}
};
TIMER.schedule(timerTask, unit.toMillis(delay));
}
} else {
task.setSchedule(true);
TimerTask timerTask = new TimerTask() {
@Override
public void run() {
if (task.isCanceled()) {
cancel();
return;
}
pool.execute(task);
}
};
TIMER.scheduleAtFixedRate(timerTask, unit.toMillis(delay), unit.toMillis(period));
}
}
@thundeGG 目前的做法是,执行前加了一个判断,如果task取消了,就不再执行timeTask
private static <T> void execute(final ExecutorService pool, final Task<T> task, long delay, final long period, final TimeUnit unit) { synchronized (TASK_POOL_MAP) { if (TASK_POOL_MAP.get(task) != null) { Log.e("ThreadUtils", "Task can only be executed once."); return; } TASK_POOL_MAP.put(task, pool); } if (period == 0) { if (delay == 0) { pool.execute(task); } else { TimerTask timerTask = new TimerTask() { @Override public void run() { if (task.isCanceled()) { cancel(); return; } pool.execute(task); } }; TIMER.schedule(timerTask, unit.toMillis(delay)); } } else { task.setSchedule(true); TimerTask timerTask = new TimerTask() { @Override public void run() { if (task.isCanceled()) { cancel(); return; } pool.execute(task); } }; TIMER.scheduleAtFixedRate(timerTask, unit.toMillis(delay), unit.toMillis(period)); } }@thundeGG 目前的做法是,执行前加了一个判断,如果task取消了,就不再执行timeTask
这中写法虽然可以解决频繁向线程池提交任务,但是TIMER还是在一直执行,我觉得应该将TIMER的创建移动到execute中,并传递给Task,外部调用Task的cancel时将TIMER进行销毁