Android Firebase - .setPersistenceEnabled(true)时启动时间较慢

时间:2017-04-18 23:41:37

标签: android firebase firebase-realtime-database

我正在开发一个简单的APOD应用程序,我在其中显示用户可以滚动的RecyclerView天文图片。我启用了FirebaseDatabase.setPersistenceEnabled(true);,因此用户可以离线使用该应用并减少连接/下载带宽。问题是如果我设置FirebaseDatabase.setPersistenceEnabled(true);,我的应用启动时间明显更长(启用6秒vs 1.5秒禁用)。我了解用户第一次启动应用时加载时间应该更长(因为设置了持久性),但是不应该每次后续启动应用都要短得多,因为它不会查询在线Firebase服务器吗?

为了防止一次加载多行,我一个接一个地发射两个SingleValueEventListeners。第一个加载100行并使用AsyncTask循环通过databaseSnapshot,然后显示图像。然后我调用第二个SingleValueEventListener并以相同的方式循环遍历它。第二个SingleValueEventListener加载剩余数据,从101 - 7000。

以下是扩展GlobalApp的{​​{1}}课程。这是我启用持久性的地方。接下来的两种方法是我加载数据的地方。

扩展应用程序类

Application

初始加载

public class GlobalApp extends Application {

@Override
public void onCreate() {
    super.onCreate();

    FirebaseDatabase mDatabaseReference = FirebaseDatabase.getInstance();

    mDatabaseReference.setPersistenceEnabled(true);

    }
}

第二次加载

 private void initialLoad() {

    databaseReference.child("apod").orderByChild("date").limitToLast(100).addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {

            new LoadFirebase().execute(dataSnapshot);

        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    });

}

如果我使用private void secondLoad() { final String secondKey = firebaseKeys.get(firebaseKeys.size() - 1); databaseReference.child("apod").orderByChild("date").endAt(secondKey).addListenerForSingleValueEvent(new ValueEventListener() { @Override public void onDataChange(DataSnapshot dataSnapshot) { new SecondLoadFirebase().execute(dataSnapshot); } @Override public void onCancelled(DatabaseError databaseError) { } }); } 启动应用,我的FirebaseDatabase.setPersistenceEnabled(true);会填充:

Logcat

接下来是一堆GC调用:

04-18 18:22:22.649 2884-2915/com.foo.apod W/CursorWindow: Window is full: requested allocation 1344 bytes, free space 752 bytes, window size 2097152 bytes
04-18 18:22:22.733 2884-2915/com.foo.apod W/CursorWindow: Window is full: requested allocation 1821 bytes, free space 1124 bytes, window size 2097152 bytes
04-18 18:22:22.798 2884-2915/com.foo.apod W/CursorWindow: Window is full: requested allocation 1580 bytes, free space 1516 bytes, window size 2097152 bytes
04-18 18:22:22.868 2884-2915/com.foo.apod W/CursorWindow: Window is full: requested allocation 1574 bytes, free space 656 bytes, window size 2097152 bytes
04-18 18:22:22.920 2884-2915/com.foo.apod W/CursorWindow: Window is full: requested allocation 1455 bytes, free space 228 bytes, window size 2097152 bytes
04-18 18:22:22.973 2884-2915/com.foo.apod W/CursorWindow: Window is full: requested allocation 1579 bytes, free space 1000 bytes, window size 2097152 bytes
04-18 18:22:23.055 2884-2915/com.foo.apod W/CursorWindow: Window is full: requested allocation 1557 bytes, free space 756 bytes, window size 2097152 bytes
04-18 18:22:23.120 2884-2915/com.foo.apod W/CursorWindow: Window is full: requested allocation 1263 bytes, free space 620 bytes, window size 2097152 bytes

似乎问题可能出在SQLite上,因为Firebase会在那里存储数据。我将Stetho添加到我的应用程序并尝试在浏览器中查看数据库(以为我在某种程度上创建了启用了持久性的重复项),但我无法访问数据库,它没有显示任何内容。

有没有人知道为什么会这样?花了很长时间才找出问题的起源。

如果您需要更多代码,请与我们联系。

由于

2 个答案:

答案 0 :(得分:4)

不幸的是,Firebase实时数据库没有实现其脱机查询的属性索引。如果您在某个位置(在您的情况下为/ apod)进行查询,则需要扫描该位置的所有缓存数据以查找匹配结果,即使只有少量数据(100或甚至1) )符合您的查询。因此,我认为您的缓慢可能是因为扫描了您存储的7000多个条目。

作为一种解决方法,如果您可以组织您的数据,以便您可以在更精细的位置阅读(例如/ apod / 2017/04 /约30个条目来查询),这可能会大大加快速度。< / p>

答案 1 :(得分:0)

我遇到了同样的问题,从Firebase阅读了许多文档后,我了解到使用

AddSingleValueEventListener

在启用persistanceMode的情况下将无法正常工作。 AddSingleValueEventListener仅侦听本地内存,而不侦听数据库本身。在运行之前它不会更新:

AddValueEventListener or ChildEventListener

请勿使用AddSingleValueEvenetListener。只能使用:

 AddValueEventListener or ChildEventListener

如果启用了持久模式