2013-05-20 23 views
5

Zaimplementowałem obserwatora zawartości historii, ale zachowuje się dziwnie. Przy każdej zmianie w historii jego funkcja onChange() działa 3-5 razy.Obserwator zawartości Androida

static class BrowserOberser extends ContentObserver { 
    public BrowserOberser() { 
     super(null); 
    } 

    @Override 
    public boolean deliverSelfNotifications() { 
     return true; 
    } 

    @Override 
    public void onChange(boolean selfChange) { 
     super.onChange(selfChange); 
     Log.d("History", "onChange: " + selfChange); 
    } 

} 

ja również zarejestrowany mój obserwatorem

BrowserOberser observer = new BrowserOberser(); 
getApplication().getContentResolver().registerContentObserver(Browser.BOOKMARKS_URI, true, observer); 

i dodano wymaganych uprawnień w manifeście.

Kod działa poprawnie, ale OnChange(); działa 3-5 razy dla każdej zmiany w historii Czy ktoś może mi pomóc w rozwiązaniu tego problemu?

+4

http://stackoverflow.com/questions/6026547/android-content-observers-onchange-method-is-called-multiple-times nie pomógł mi. – anon

+3

Zauważyłem, że różnica między pierwszym a trzecim runem była taka: W pierwszym uruchomieniu tytuł jest taki sam jak adres URL, ale w trzecim uruchomieniu obecny jest odpowiedni tytuł. Może dlatego, że są to etapy ładowania stron. Ale co to właściwie jest? I dlaczego liczba przebiegów różni się? – anon

+0

proszę zostawić komentarz, jeśli potrzebujesz więcej informacji – anon

Odpowiedz

2

To jak w końcu rozwiązać ten problem dla mojej sprawy Atleast (chciałem czytać historię, gdy istnieje zmiana w historii)

@Override 
    public void onChange(boolean selfChange) { 
     super.onChange(selfChange); 
     /** 
     * Get SharedPreferneces of the user 
     */ 
     SharedPreferences pref= myContext.getSharedPreferences("com.tpf.sbrowser", 
       Context.MODE_PRIVATE); 
     long wherelong = pref.getLong("Date", 0); 
     DatabaseManager db=new DatabaseManager(myContext,1); 
     String[] proj = new String[] { Browser.BookmarkColumns.TITLE, 
       Browser.BookmarkColumns.URL, BookmarkColumns.DATE,}; 
     String sel = Browser.BookmarkColumns.BOOKMARK + " = 0"; 
     Cursor mCur = myContext.getContentResolver().query(
       Browser.BOOKMARKS_URI, proj, sel, null, null); 
     Log.d("onChange", "cursorCount"+mCur.getCount()); 
     mCur.moveToFirst(); 
     String title = ""; 
     String url = ""; 
     long lastVisitedDate=0; 
     DbMessage msg = new DbMessage(lastVisitedDate,url, title); 
     /** 
     * Start reading the user history and dump into database 
     */ 
     if(mCur.moveToFirst() && mCur.getCount() > 0) { 
       while (mCur.isAfterLast() == false) { 
        title =mCur.getString(0); 
        url = mCur.getString(1); 
        lastVisitedDate =mCur.getLong(2); 
        if ((lastVisitedDate>wherelong) && (!title.equals(url))) { 
         msg.set(lastVisitedDate, url, title); 
         db.InsertWithoutEnd(msg); 
         pref.edit().putBoolean("BrowserHistoryRead", true).commit(); 
         pref.edit().putLong("Date", lastVisitedDate).commit(); 
         myContext.updateTime(wherelong,lastVisitedDate); 
         wherelong=lastVisitedDate; 
        } 
        mCur.moveToNext(); 
       } 
      } 
    } 

Ale nadal, jeśli byłoby wspaniale, gdyby ktoś mógłby powiedzieć, która iteracji onChange (w prostym kodzie pytania) odpowiada dokładnie temu stanowi ładowania strony. Z tego, czego się dowiedziałem, w pierwszym tytule powtórzenia był taki sam jak adres URL, aw trzeciej iteracji był obecny prawidłowy tytuł strony. Ale podczas przekierowywania, naChange został wezwany do 5 razy. Czy ktoś może potwierdzić, na podstawie którego iteracji współbrzmią?

0

Dokładny sposób aktualizowania historii to szczegół implementacji, na który prawdopodobnie nie chcesz polegać. Zamiast próbować odgadnąć, czy aktualizacja została zakończona, czy nie w oparciu o wartości różnych pól, sugerowałbym restartowanie timera za każdym razem, gdy wywoływano onChange(..). Jeśli upłynie czas, możesz być pewien, że historia została zakończona.

Edit Przykład jak używać czasomierza:

static class BrowserOberser extends ContentObserver implements Runnable { 
    private Handler h; 

    public BrowserOberser() { 
     super(null); 
     h = new Handler(); 
    } 

    @Override 
    public boolean deliverSelfNotifications() { 
     return true; 
    } 

    @Override 
    public void onChange(boolean selfChange) { 
     super.onChange(selfChange); 
     h.removeCallbacks(this); 
     h.postDelayed(this, 500); 
    } 

    public void run() { 
     Log.d("history observer", "change timer elapsed"); 
    } 

} 
+1

Cóż, jest to również miłe podejście i próbowałem, ale to nie zadziałało.1) Zgadywanie, kiedy historia zakończyła aktualizację, może być trudne. Załóżmy, że użytkownik traci połączenie internetowe podczas ładowania strony, co spowoduje, że tytuł będzie taki sam jak adres URL (to na podstawie mojej faktycznej obserwacji). 2) W jaki sposób proponujesz go wdrożyć? 'onChange()' będzie wywoływane 5 razy dla każdego adresu url, więc nie możesz go po prostu wstrzymać, ponieważ to nie przyniesie pożądanego rezultatu. – anon

+0

Jeśli możesz mi powiedzieć, jaki jest dokładny sposób aktualizowania historii, byłabym wdzięczna (oczywiście, że nagroda jest także twoja). – anon

+0

zaktualizowany z przykładowym kodem jak wdrożyć taki zegar –

1

myślę, że może znajdę odpowiedź. Po pierwsze chcę powiedzieć, że mój angielski jest ograniczony, mam nadzieję, że mnie zrozumiecie.

Rzeczywiście, onChange(); działa kilka razy dla każdej zmiany w historii, co najmniej dwa razy.

Ponieważ kiedy użytkownik przegląda witrynę za pomocą przeglądarki, system dodaje historię do bazy danych i wywołuje onChange();. Ale teraz system nie zna tytułu adresu URL. Po uzyskaniu przez system nazwy adresu URL system aktualizuje bazę danych, a onChange(); nazywa się po raz drugi.

A jeśli adres URL przekierowuje w czasie, za każdym razem, gdy system otrzyma nowy adres URL, system również zaktualizuje bazę danych, więc onChange(); jest również nazywany. Tak więc myślę, że w Change będzie się nazywał kilka razy każdą zmianą. Mam nadzieję, że rozumiesz mój angielski.

Powiązane problemy