2017-04-18 60 views
0

我正在研究一個簡單的APOD應用程序,其中顯示用戶可滾動瀏覽的天文圖片RecyclerView。我啓用了FirebaseDatabase.setPersistenceEnabled(true);,以便用戶可以脫機使用該應用程序並減少連接/下載帶寬。問題是如果我設置FirebaseDatabase.setPersistenceEnabled(true);,我的應用程序啓動時間會明顯更長(啓用6秒而禁用1.5秒)。我知道用戶第一次啓動應用程序時,加載時間應該更長(因爲持久性已設置),但是不應該每次後續啓動應用程序的時間明顯縮短,因爲它不查詢在線Firebase服務器?Android Firebase - .setPersistenceEnabled時啓動速度緩慢(true)

爲了防止一次加載多行,我一個接一個地打開兩個SingleValueEventListeners。第一個加載100行並使用AsyncTask循環訪問databaseSnapshot,然後顯示圖像。然後我打電話給第二個SingleValueEventListener並以相同的方式循環。第二個SingleValueEventListener加載其餘數據,從101 - 7000.

以下是我的GlobalApp類延伸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填滿了:

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,因爲火力地堡存儲有數據。我將Stetho添加到我的應用程序,並試圖在瀏覽器中查看數據庫(認爲我以某種方式創建了啓用了持久性的重複項),但我無法訪問數據庫,它什麼也沒有顯示。

有沒有人有線索爲什麼發生這種情況?花了很長時間才能找出問題出在哪裏。

如果您需要更多代碼,請讓我知道。

謝謝

+1

當您啓用磁盤持久性時,Firebase客戶端在開始重建其內部數據模型時會從磁盤緩存中讀取所有數據。取決於數據的大小和數據模型的複雜性(大致:節點/值的數量),這肯定會花費一些時間。 –

回答

3

不幸的是,Firebase實時數據庫沒有實現其離線查詢的屬性索引。如果您在某個位置執行查詢(您的情況爲/ apod),則需要掃描該位置的所有緩存數據,以便查找匹配的結果,即使只有一小部分(100或甚至1) )匹配您的查詢。所以我認爲你的緩慢可能是由於掃描了你存儲的7000多個條目。

作爲一種解決方法,如果您可以組織數據以便可以在更精細的位置閱讀(例如/ apod/2017/04/with〜30個條目以進行查詢),那麼這可能會大大加快速度。

+0

這產生了巨大的差異。我的啓動時間基本上不存在..不到1秒。非常感謝你的幫助! –

+0

好聽!感謝您的跟蹤。 :-) –