【问题标题】:How to pause UI thread until Firebase query is finished?如何在 Firebase 查询完成之前暂停 UI 线程?
【发布时间】:2016-11-22 12:37:11
【问题描述】:

所以我的问题说明了一切。在 onCreate 中,我试图查询对象,但我希望 UI 线程等到我完成对所有对象的查询,这样我就可以使用它们来创建我的用户可以看到的视图。有谁知道如何使用示例代码来做到这一点?

这是我的查询方式。

 Firebase cardReference = mRef.child("aReference");
        cardReference.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                for (DataSnapshot dataSnapshot1 : dataSnapshot.getChildren()) {
                    CardModel fireBaseCard = dataSnapshot1.getValue(CardModel.class);
                    testCardModelArray.add(fireBaseCard);
                    cardStack.setCardModelIDInArrayList(fireBaseCard.getCardID());
                }
                setUpCardStack();
            }

            @Override
            public void onCancelled(FirebaseError firebaseError) {

            }
        });

希望大家帮忙!

【问题讨论】:

  • 使用加载屏幕直到您完成查询?
  • 您绝对不想冻结 UI 线程。那是用户体验的地狱,也是失去应用下载量的必经之路。使用某种加载机制(进度条、加载屏幕等)
  • 你最好使用闪屏(活动)。请参阅此示例:androidhive.info/2013/07/…
  • 试图让 UI 线程等待是一个坏主意(有关详细信息,请参阅 my answer here)。而是将您的想法从“首先我们获取数据,然后我们更新 UI”重新定义为“当我们获得日期时,我们更新 UI”。一个很好的例子可以在Firebase quickstart app for the database 中找到,但也可能在大多数其他 Firebase Android 教程中。
  • @LubomirBabev Splashscreen 通常是我想要的。

标签: android multithreading firebase firebase-realtime-database querying


【解决方案1】:

嗯,所以你想在单独的后台线程中运行你的东西?

首先,创建一个私有布尔值:

private boolean isQueryingFinished = false

在 onCreate 中写入:

Thread thread = new Thread(new Runnable() {
    @Override
    public void run() {
        // do your stuff here
        isQueryingFinished = true;
    }
});
thread.start();
while(!isQueryingFinished);

这将等到线程完成后在 onCreate() 中继续你的东西

你也可以这样做:

while(!isQueryingFinished) {
    try {
        Thread.sleep(500);
    } catch(Exception ex) {/* */}
}

这样,它会每 0.5 秒(500 毫秒)检查一次是否完成。

但我不认为那很好。

所以也许使用某种监听器会更好:

public interface QueryFinishedListener {
    void onQueryFinished();
}

然后在你的活动中定义它:

private QueryFinishedListener mQueryFinishedListener;

现在在 onCreate() 中新建一个:

mQueryFinishedListener = new QueryFinishedListener() {
    public void onQueryFinished() {
        // do whatever you need to do when finished
    }
};
// do your query stuff here
mQueryFinishedListener.onQueryFinished();

同样,我不认为这真的很有用,因为如果您正在做一些需要更长时间的事情,UI 会自动冻结。

【讨论】:

  • Firebase 已经在主 UI 线程之外运行其数据同步。把它放在另一个线程中不会有帮助。完成监听器是个好主意。但请记住,Firebase 的 ValueEventListener 已经是一个完成处理程序。
【解决方案2】:

您应该使用 AsyncTask。将所有代码放在 doInBackground 方法中,然后在 onPostExecute 中制作一个类似于微调器或其他东西的动画。 `mAsyncTask = new AsyncTask() {

            @Override
            protected String doInBackground(Void... voids) {
                //put your code here
            }

            @Override
            protected void onPostExecute(String s) {
                //make a spinner here
            }
        };
        mAsyncTask.execute();`

【讨论】:

  • Firebase 已经在主 UI 线程之外运行其数据同步。把它放在AsyncTask 是没有帮助的。
  • @Gorg 是的,我想我会像 Frank 在上面的 cmets 中指出的那样实现启动画面。
猜你喜欢
  • 1970-01-01
  • 2020-02-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-23
  • 2011-02-21
  • 1970-01-01
相关资源
最近更新 更多