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

Android Firebase-启用.setPersistenceEnabled时启动时间缓慢(true),android,firebase,firebase-realtime-database,Android,Firebase,Firebase Realtime Database,我正在开发一个简单的APOD应用程序,其中我显示了一个天文图片的RecyclerView,用户可以滚动浏览。我启用了FirebaseDatabase.setPersistenceEnabled(true)这样用户就可以脱机使用应用程序并减少连接/下载带宽。问题是如果我设置了FirebaseDatabase.setPersistenceEnabled(true),我的应用程序启动时间明显更长(启用6秒,禁用1.5秒)。我知道用户第一次启动应用程序时,加载时间应该更长(因为设置了持久性),但应用程序

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

为了避免一次加载多行,我启动了两个
SingleValueEventListeners
。第一个使用
AsyncTask
加载100行并循环数据库快照,然后显示图像。然后调用第二个
SingleValueEventListener
,并以相同的方式循环它。第二个
SingleValueEventListener
加载剩余的数据,从101到7000

下面是我的
GlobalApp
类,它扩展了
应用程序。这就是我启用持久性的地方。接下来的两个方法是我加载数据的地方

扩展应用程序类

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) {

        }
    });

}
第二次加载

 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)启动应用程序,my
Logcat
填充有:

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
然后是一组GC调用:

04-18 18:22:26.290 2884-2891/com.foo.apod I/art: Background partial concurrent mark sweep GC freed 171401(23MB) AllocSpace objects, 0(0B) LOS objects, 15% free, 85MB/101MB, paused 2.120ms total 151.451ms
04-18 18:22:29.153 2884-2891/com.foo.apod I/art: Background partial concurrent mark sweep GC freed 552106(22MB) AllocSpace objects, 4(1096KB) LOS objects, 15% free, 84MB/100MB, paused 868us total 158.171ms
04-18 18:22:29.647 2884-2891/com.foo.apod I/art: Background sticky concurrent mark sweep GC freed 211953(18MB) AllocSpace objects, 0(0B) LOS objects, 14% free, 85MB/100MB, paused 2.590ms total 114.968ms
04-18 18:22:30.122 2884-2891/com.foo.apod I/art: Background sticky concurrent mark sweep GC freed 482294(17MB) AllocSpace objects, 43(3MB) LOS objects, 3% free, 96MB/100MB, paused 1.440ms total 100.242ms
04-18 18:22:31.091 2884-2906/com.foo.apod V/FA: Inactivity, disconnecting from the service
看来问题可能出在SQLite上,因为Firebase将数据存储在那里。我添加到我的应用程序中,并试图在浏览器中查看数据库(认为我在某种程度上创建了启用持久性的副本),但我无法访问数据库,它没有显示任何内容

有人知道为什么会这样吗?花了很长时间才找到问题的根源

请让我知道,如果你需要更多的代码


感谢

不幸的是,Firebase实时数据库没有实现其脱机查询的属性索引。如果在某个位置执行查询(在本例中为/apod),它将需要扫描该位置的所有缓存数据,以便找到匹配的结果,即使只有一小部分(100甚至1)与您的查询匹配。因此,我认为您的速度缓慢可能是因为扫描了您存储的7000多个条目


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

我也遇到同样的问题,在阅读了firebase的许多文档后,我了解到使用:

AddSingleValueEventListener
启用persistanceMode时,将无法正常工作。AddSingleValueEventListener只侦听本地内存,而不侦听数据库本身。在您运行以下命令之前,它不会更新:

AddValueEventListener or ChildEventListener
不要使用AddSingleValueEvenetListener。仅限使用:

 AddValueEventListener or ChildEventListener

如果启用磁盘持久性时启用了持久性模式

,Firebase客户端将在开始重建其内部数据模型时从磁盘缓存读取所有数据。这肯定需要一些时间,这取决于数据的大小和数据模型的复杂性(大致为:节点/值的数量)。这造成了巨大的差异。我的启动时间基本上不存在。。不到1秒。非常感谢你的帮助!很高兴听到!感谢您的跟进。:-)