【问题标题】:why does onStart() method run before onCreate in my android project?为什么 onStart() 方法在我的 android 项目中的 onCreate 之前运行?
【发布时间】:2019-11-17 09:46:08
【问题描述】:

根据activity的生命周期,onCreate()在app创建时被调用一次,随后的onStart()方法在整个activity生命周期中可能会被调用多次。然而,这不是发生在我身上的事情。

我的 onCreate 方法中有这段代码:

mRef.addChildEventListener(new ChildEventListener() {
            @Override
            public void onChildAdded(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {


                Gig thisGig =  dataSnapshot.getValue(Gig.class);

                loadedGigs.add(thisGig);
                Log.w("onCreate", "There are " + loadedGigs.size() + "Gigs loaded in the array.");


                arrayAdapter.notifyDataSetChanged();
            }

            @Override
            public void onChildChanged(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {

            }

            @Override
            public void onChildRemoved(@NonNull DataSnapshot dataSnapshot) {

            }

            @Override
            public void onChildMoved(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {

            }

            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {

            }
        });

然后我有我的 onStart 方法:

@Override
    protected void onStart()
    {
        super.onStart();
        Log.w("onStart", "There are " + loadedGigs.size() + "Gigs loaded in the array.");


    }

这里是日志:

V/FA: onActivityCreated
W/onStart: There are 0Gigs loaded in the array.
V/FA: Activity resumed, time: 2460468116
D/FA: Logging event (FE): screen_view(_vs), Bundle[{ga_event_origin(_o)=auto, ga_previous_class(_pc)=search_gigs_activity, ga_previous_id(_pi)=-5229767692724064313, ga_screen_class(_sc)=search_gigs_results_activity, ga_screen_id(_si)=-5229767692724064312}]
D/NetworkSecurityConfig: No Network Security Config specified, using platform default
W/onCreate: There are 1Gigs loaded in the array.
W/onCreate: There are 2Gigs loaded in the array.
W/onCreate: There are 3Gigs loaded in the array.
V/FA: Inactivity, disconnecting from the service

我有其他代码,但我将其全部删除,因为我不断收到空指针异常并且无法弄清楚原因。原来我试图从 onStart 方法内部访问“loadedGigs”数组列表,认为它已经从 onCreate 方法填充。

关于为什么会发生这种情况的任何想法?我最好的猜测是它与我使用 Firebase 和子事件侦听器有关。我缺乏相当多的知识,我想这就是我无法弄清楚的原因。

提前谢谢, 弗拉德

【问题讨论】:

    标签: java android oncreate onstart


    【解决方案1】:

    事实核查

    事实上,首先调用onCreate(),然后调用onStart()。但是因为您正在调用 firebase 来获取您的数据集,所以您的 onStart() 不会等待此操作完成,这意味着您在 onStart 中的列表仍未填充。请记住,当调用onCreate 时,无论在那里执行什么代码,它都不会暂停onStart 的调用。同样,onStart 不会等待onCreate 中的所有代码完成,然后再执行它自己的代码。

    您的问题

    在您从 onCreate 中的 firebase eventlisteners 获取数据集之后,您似乎想在 onStart 中执行某些操作。我

    建议?

    您可以使用LiveDataonStart 中的代码知道firebase 事件侦听器已完成,并准备好您需要在onStart 中使用的数据。

    您询问的实时数据是什么?

    LiveData 是一个可观察的数据持有者类。不同于一般的 可观察的,LiveData 是生命周期感知的,这意味着它尊重 其他应用程序组件的生命周期,例如活动、片段或 服务。这种意识确保 LiveData 只更新应用程序组件 处于活动生命周期状态的观察者。

    查看更多here

    会是什么样子:

    //just add dependency into the app/build.gradle .
    def lifecycle_version = "1.1.1"
    implementation "android.arch.lifecycle:extensions:$lifecycle_version"
    annotationProcessor "android.arch.lifecycle:compiler:$lifecycle_version"
    
    
    // Create an instance of LiveData to hold your firebase dataset eg List of Gig object
    private MutableLiveData<List<Gig>> myGigLiveData;
    
    .......
    //initialize inside onCreate()
    myGigLiveData = new MutableLiveData<>();
    
    .......
    
    mRef.addChildEventListener(new ChildEventListener() {
                @Override
                public void onChildAdded(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {
    
                    Gig thisGig =  dataSnapshot.getValue(Gig.class);
    
                    loadedGigs.add(thisGig);
                    Log.w("onCreate", "There are " + loadedGigs.size() + "Gigs loaded in the array.");
    
    
                    arrayAdapter.notifyDataSetChanged();
                    
                    //set the dataset value to livedata
                    myGigLiveData.setValue(loadedGigs);
                }
                ...............
                
                
                
                //observe the livedata in onStart like so:
                @Override
        protected void onStart()
        {
            super.onStart();
           
    myGigLiveData.observe(this, gigsList ->{
    Log.w("onStart", "There are " + gigsList.size() + "Gigs loaded in the array.");
    });
    
        }

    【讨论】:

    • 这是一个非常有用的答案。很少有事情……您在观察 myGigLiveData 时使用的 gigsList 是什么?还有……在观察什么?如何进一步访问我正在观察的这些数据?我希望能够按索引访问这些加载的演出(也许?,可能有数百万次演出)并进一步访问这些对象存储的一些数据。
    • gigsList 是变化观察者。它可以是您需要观察的任何类型的数据类型。 LiveData 只是帮助您订阅来自任何地方的数据更改。您可以在这里了解更多信息medium.com/@elye.project/…
    • 我相信这里发布的几乎所有答案都澄清了您的问题。有关如何加载更多演出的问题,请打开另一个问题。接受其中一个答案,这样问题就不会一直悬而未决。
    【解决方案2】:

    在您的活动中 onCreate() 在 onStart() 之前调用,但在您的 onCreate() 方法中您只添加 childEventListener,而事件 onChildAdded 仅在调用 onStart() 之后发生,并且这就是您在日志中看到的内容。

    【讨论】:

    • 这确实是正在发生的事情。
    • 是的。你说得对。谢谢,我明白它现在是如何工作的了。
    【解决方案3】:

    您开始在onChildAdded 回调中填充您的loadedGigs 列表,该回调(在您的情况下)在活动的onStart() 调用之后触发。

    根据文档,ChildEventListener"appropriate method will be triggered when changes occur" 意味着它会在未来的某个时刻以异步方式发生,因此您不应期望您的数据存在于活动的 onStart() 中。

    还有一件事。您的Log.w("onCreate",...) 与活动的生命周期onCreate(Bundle savedInstanceState) 无关,这样的日志输出消息可能会造成混淆。

    【讨论】:

    • 很好的解释。我希望OP现在已经理解了这一点。
    • 是的,我现在看到了。谢谢。并感谢指出日志的事情。你完全正确。关于如何在 onCreate() 中加载我的数据库数据并在 onStart() 期间访问它的任何建议?
    • 我不建议您将这两个完全不相关的流程混合在一起。您最好(从用户体验的角度)做的是订阅 onCreate 中的 Firebase 参考更新(就像您现在已经在做的那样)并在您的 UI 上显示一些 ProgressBar 直到最终触发 ChildEventListener 回调。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多