2013-05-20 17 views
5

Ich implementiert Content-Beobachter der Geschichte, aber es verhält sich seltsam. Für jede Änderung in der Geschichte seine OnChange() -Funktion läuft 3-5 mal.Android Geschichte Content Observer

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); 
    } 

} 

ich registrierte auch meinen Beobachter

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

und hinzugefügt erforderliche Berechtigungen in manifest werden.

Der Code funktioniert gut, aber onChange(); Läuft 3-5 Mal für jede Änderung in der Geschichte
Kann mir jemand mit einer Lösung für dieses Problem helfen?

+4

http://stackoverflow.com/questions/6026547/android-content-observers-onchange-method-is-called-multiple-times war mir keine Hilfe. – anon

+3

Was ich beobachtete, war, dass der Unterschied zwischen dem ersten und dritten Lauf war: Im ersten Lauf ist Titel gleich wie URL, aber im dritten Lauf ist der entsprechende Titel vorhanden. Vielleicht liegt es daran, dass die Seiten geladen sind. Aber was genau ist das? Und warum unterscheidet sich die Anzahl der Läufe? – anon

+0

Bitte hinterlassen Sie einen Kommentar, wenn Sie weitere Informationen benötigen – anon

Antwort

2

Dies ist, wie ich das Problem für meinen Fall atleast endlich gelöst (wollte ich die Geschichte lesen, wenn eine Veränderung in der Geschichte gibt es)

wäre, wenn
@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(); 
       } 
      } 
    } 

aber immer noch groß, wenn jemand der Iteration von onChange sagen könnte, (im einfachen Code der Frage) entspricht genau dem Zustand beim Seitenladen. Von dem, was ich gelernt habe, in der ersten Iteration war Titel wie URL und in der dritten Iteration war der korrekte Seitentitel vorhanden. Aber während der Umleitung wurde onChange bis zu 5 Mal aufgerufen. Kann also jemand bestätigen, welche Iteration zu welcher Phase gehört?

0

Die genaue Art und Weise, in der der Verlauf aktualisiert wird, ist ein Implementierungsdetail, auf das Sie sich wahrscheinlich nicht verlassen möchten. Anstatt zu versuchen, zu erraten, ob das Update abgeschlossen ist oder nicht, basierend auf den Werten verschiedener Felder, würde ich vorschlagen, einen Timer jedes Mal neu zu starten, wenn onChange(..) aufgerufen wird. Wenn der Timer abläuft, können Sie sicher sein, dass der Verlauf der Aktualisierung abgeschlossen ist.

bearbeiten Beispiel dafür, wie ein Timer zu verwenden:

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

Nun, das ist ein netter Ansatz auch und ich habe es versucht, aber es hat nicht funktioniert.1) Raten, wenn die Geschichte die Aktualisierung beendet hat, kann auch schwierig sein. Angenommen, der Benutzer verliert während des Ladens der Seite die Internetverbindung, wodurch der Titel der URL entspricht (dies basiert auf meiner tatsächlichen Beobachtung). 2) Wie schlagen Sie vor, es zu implementieren? 'onChange()' wird 5 Mal für jede URL-Ladung aufgerufen, so dass Sie es nicht einfach pausieren können, da dies nicht das gewünschte Ergebnis liefert. – anon

+0

Und wenn Sie mir sagen können, wie genau die Geschichte aktualisiert wird, wäre ich dankbar (natürlich gehört auch die Prämie Ihnen). – anon

+0

aktualisiert mit Beispielcode, wie man einen solchen Timer implementiert –

1

glaube ich, die Antwort finden kann. Zuerst möchte ich sagen, dass mein Englisch begrenzt ist, ich hoffe, dass Sie mich verstehen können.

In der Tat, onChange(); läuft mehrmals für jede Änderung in der Geschichte, mindestens zwei Mal.

Da, wenn Benutzer den Browser verwenden, um eine Website zu durchsuchen, fügt das System einen Verlauf in der Datenbank hinzu, und onChange(); wird aufgerufen. Aber im Moment kennt das System den Titel der URL nicht. Nachdem das System den Titel der URL erhalten hat, aktualisiert das System die Datenbank und onChange(); wird zweites Mal aufgerufen.

Und wenn die URL während der Zeit umleitet, aktualisiert das System jedes Mal, wenn das System eine neue URL erhält, auch die Datenbank, also onChange(); heißt auch. Also ich denke onChange wird bei jeder Änderung mehrmals aufgerufen. Hoffe, du kannst mein Englisch verstehen.