Android生命周期库:无法添加具有不同生命周期的相同观察者

The*_*mer 11 android android-lifecycle

我有一个正在研究的应用程序,它正在使用生命周期库,但我得到一个IllegalArgumentException,上面写着"无法添加具有不同生命周期的相同观察者"我只在onCreate中添加了观察者,我认为这是安全的.我的大多数观察者都是通过匿名类添加的,我认为这不是问题所在,因为观察者永远不会被回收.一个是使用this:

private GpsState gpsState;

void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    getLifecycle().addObserver(gpsState);
    gpsState.observe(this, (state) -> {
        // ...
    });
}
Run Code Online (Sandbox Code Playgroud)

在该示例中,GpsState扩展LiveData以提供GPS的当前状态并且实现LifecycleObserver为能够在达到ON_RESUME状态时刷新某些值.

知道我可能做错了什么吗?

Nok*_*uap 23

在我的情况下,问题是lambda方法的观察者是空的.我只是尝试添加一些东西,问题解决了.例如:

gpsState.observe(this, (state) -> {
                Log.d(this.getClass().getSimpleName(), BaseNavigationActivity.this.toString());

});
Run Code Online (Sandbox Code Playgroud)

很可能JVM定义了仅使用静态引用的匿名类,对于这种情况,它变得有点单例,因此在引用此类时,您将拥有相同的实例.

  • 非常接近,它不是空的,但它只访问静态对象,我猜这使得编译器重用相同的实例. (8认同)
  • 是的,看来你必须添加一些动态的东西 (2认同)

Kev*_*tel 6

正如thehebrewhammer在评论中所说,由于Kotlin SAM-Lambda优化,我遇到了同样的问题。

viewModel.myLiveData.observe(this, Observer {
    NavigationBackEvent().post()
})
Run Code Online (Sandbox Code Playgroud)

此SAM-Lambda不访问任何类,将被编译为单例以进行优化。
我将其更改为用于在每次运行时强制使用新实例的类初始化:

viewModel.myLiveData.observe(this, MyObserver())
Run Code Online (Sandbox Code Playgroud)

class MyObserver : Observer<MyType?> {
    override fun onChanged(it: MyType?) {
        NavigationBackEvent().post()
    }
}
Run Code Online (Sandbox Code Playgroud)

  • @VasilyKabunov 这都与如果您不访问“父类”的字段有关。如果您访问一个,编译器会生成一个“内部类”。如果您不访问,则无需多次实例,它始终相同。编译器将对其进行优化并生成单例。 (2认同)

小智 6

我遇到了同样的问题,这些代码行解决了它:

sharedViewModel.getFriendsList().observe(this, object: Observer<ArrayList<User>> {
    override fun onChanged(t: ArrayList<User>?) {
        CurrentUser.friendsList = t
    }
})
Run Code Online (Sandbox Code Playgroud)