Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/381.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/180.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java ViewLifeCycleOwner再次从主线程转到后台到主线程时返回null_Java_Android_Multithreading_Android Lifecycle_Weak References - Fatal编程技术网

Java ViewLifeCycleOwner再次从主线程转到后台到主线程时返回null

Java ViewLifeCycleOwner再次从主线程转到后台到主线程时返回null,java,android,multithreading,android-lifecycle,weak-references,Java,Android,Multithreading,Android Lifecycle,Weak References,我需要在适配器解析其视图后的几毫秒内开始观察,以便它们正确接收信号 此方法在onViewCreated()之后执行 其中Post.delayed()是一个Executors.newSingleThreadScheduledExecutor().schedule()方法,而Post.onMain()是一个新处理程序(Looper.getMainLooper())用于可运行的过帐 奇怪的事情正在发生…: 第一次执行代码时,一切正常,但在配置更改后,会发生IllegalStateException:

我需要在适配器解析其视图后的几毫秒内开始观察,以便它们正确接收信号

此方法在onViewCreated()之后执行

其中
Post.delayed()
是一个
Executors.newSingleThreadScheduledExecutor().schedule()
方法,而
Post.onMain()
是一个
新处理程序(Looper.getMainLooper())用于可运行的过帐

奇怪的事情正在发生…:

第一次执行代码时,一切正常,但在配置更改后,会发生
IllegalStateException

@MainThread
    @NonNull
    public LifecycleOwner getViewLifecycleOwner() {
        if (mViewLifecycleOwner == null) {
            throw new IllegalStateException("Can't access the Fragment View's LifecycleOwner when "
                    + "getView() is null i.e., before onCreateView() or after onDestroyView()");
        }
        return mViewLifecycleOwner;
    }
但是。。。如果我调用
getViewLifeCycleOwner()
;在进入
.getMainLooper()
线程之前,在
Post.delayed()
Post.onMain()
之间,如下所示:

                        Post.delayed(
                                () -> {
                                    getViewLifecycleOwner();
                                    Post.onMain(
                                            () -> {
                                                currentPage.observe(getViewLifecycleOwner(),
                                                        page -> {
                                                            selector.setSelected(page);
                                                            binding.searchPages.setCurrentItem(page, true);
                                                        }
                                                );
                                            }
                                    );

                                },
                                150L,
                                TimeUnit.MILLISECONDS
                        );
代码工作

我怀疑正在发生的是…:

/**
     * The provider that owns this Lifecycle.
     * Only WeakReference on LifecycleOwner is kept, so if somebody leaks Lifecycle, they won't leak
     * the whole Fragment / Activity. However, to leak Lifecycle object isn't great idea neither,
     * because it keeps strong references on all other listeners, so you'll leak all of them as
     * well.
     */
    private final WeakReference<LifecycleOwner> mLifecycleOwner;
/**
*拥有此生命周期的提供程序。
*只保留LifecycleOwner上的WeakReference,所以如果有人泄漏Lifecycle,他们就不会泄漏
*整个片段/活动。但是,泄露生命周期对象也不是什么好主意,
*因为它在所有其他侦听器上保留强引用,所以您会将所有侦听器作为
*嗯。
*/
私人最终财产所有者;
WeakReference正在
Post.delayed()
(调度执行器)中被GC'd,因此当需要在
主线程中再次执行该方法时,该引用已被收集,但当在后台调度执行器中执行该方法的第二次执行时,即使根本不使用引用,线程也会保留方法
getViewLifeCycleOwner()
中涉及的所有引用的副本,并在返回到
mainThread
时退出垃圾收集


我的预感正确吗?

所以这不是正在发生的事情…,是的,只是部分。 新的线程不是在“收集”WeakReference,而是在“延长”它的寿命。 怎么用?getViewLifeCycle()方法在延迟方法指定的150毫秒之前执行时,有助于绕过IllegalStateException(),并带来LifecycleRegistry的副本,该副本在方法执行时已被销毁。。。谢天谢地,LiveData组件可以完成
返回当生命周期已经被破坏并且一切都结束时

真正的问题与空状态、初始状态和以前保存的状态有关

在配置更改发生之前,堆栈中已经存在的片段再次被相同的片段替换,这一切都是因为上层组件忽略了相等性,这种破坏比延迟方法指定的150毫秒要快

这就是在
Executors.newSingleThreadScheduledExecutor().schedule()
可以访问该视图之前销毁该视图的原因

起初我以为问题出在泛型枚举的相等性检查上(因为它忽略了新对象,但这是相反的问题,所以…),但允许重复操作通过的事情。。。实际上,所述组件上的“启动状态”在配置更改时触发(更准确地说:onViewCreated),因此相等性检查无法推断堆栈上已存在真实的最后一个操作/片段

解决方案是检查新旧之间的Fragment class()相等性,以防止重复事务

另一种选择是对配置更改进行特殊处理,并使组件了解此状态,但在任何代码IMO中,重复的事务/操作通常都是一个不好的迹象,因此最好的做法是防止重复操作

/**
     * The provider that owns this Lifecycle.
     * Only WeakReference on LifecycleOwner is kept, so if somebody leaks Lifecycle, they won't leak
     * the whole Fragment / Activity. However, to leak Lifecycle object isn't great idea neither,
     * because it keeps strong references on all other listeners, so you'll leak all of them as
     * well.
     */
    private final WeakReference<LifecycleOwner> mLifecycleOwner;