1.背景
Android项目中遇到下面异常java.lang.IllegalArgumentException: Cannot add the same observer with different lifecycles。抛出异常的代码段如下:
public void observe(LifecycleOwner owner,Observer<? super T> observer) {
...
LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
if (existing != null && !existing.isAttachedTo(owner)) {
throw new IllegalArgumentException("Cannot add the same observer"
+ " with different lifecycles");
}
if (existing != null) {
return;
}
owner.getLifecycle().addObserver(wrapper);
}
2.复现问题
准备了一段代码来模拟复现这个问题。
2.1模拟复现的代码如下
import java.util.HashMap;
public class Test{
public static void main(String[] args){
System.out.println("test main");
Test t = new Test();
t.clearTask();
t.addTask(1);
t.addTask(2);
t.printTaskSize();
}
private HashMap<Runnable, Integer> mTasks = new HashMap<>();
private void clearTask(){
mTasks.clear();
}
private void printTaskSize(){
System.out.println("taskSize=" + mTasks.size());
}
private void work() {
System.out.println("work.");
}
public void addTask(int i) {
Runnable task = () -> {
//work();
};
System.out.println("addTask task=" + task);
mTasks.put(task, Integer.valueOf(i));
}
}
2.2模拟代码输出的结果如下
test main
addTask task=Test$$Lambda$1/531885035@816f27d
addTask task=Test$$Lambda$1/531885035@816f27d
taskSize=1
从输出结果可以看出,lamda表达式的两个对象的地址是一样的,会导致HashMap的size不正确。
2.3 更改代码
将//work();这一行代码的注释去掉,运行结果如下:
test main
addTask task=Test$$Lambda$1/531885035@1218025c
addTask task=Test$$Lambda$1/531885035@816f27d
taskSize=2
从输出结果可以看出HashMap的size是正确的了。
3.原因
暂时未知。