5

역사의 내용 관찰자를 구현했지만 이상하게 행동합니다. 히스토리의 모든 변경 사항에 대해 onChange() 함수는 3-5 회 실행됩니다. 안드로이드 이력 내용 옵저버

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

} 

는 또한

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

를 사용하여 내 관찰자 등록 된 매니페스트에 필요한 권한을 추가했다.

코드는 제대로 작동하지만 onChange(); 기록에서 변경 될 때마다 3-5 회 실행
누구든지이 문제에 대한 해결책을 도울 수 있습니까?

+4

http://stackoverflow.com/questions/6026547/android-content-observers-onchange-method-is-called-multiple-times는 나에게 도움이되지 않았습니다. – anon

+3

내가 관찰 한 것은 첫 번째 실행과 세 번째 실행의 차이점은 다음과 같습니다. 첫 번째 실행 제목은 url과 동일하지만 세 번째 실행에서는 적절한 제목이 표시됩니다. 따라서 페이지가로드되는 단계 일 수 있습니다.하지만 정확히 무엇입니까? 그리고 달리기 횟수가 다른 이유는 무엇입니까? – anon

+0

더 많은 정보가 필요하면 의견을 남겨주세요. – anon

답변

2

이 나는 ​​마침내 내 경우이어야에 대한 문제를 해결하는 방법입니다

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

를 (I 역사의 변화가있을 때 역사를 읽고 싶어)하지만 여전히 누군가의 onChange의 어느 반복을 말할 수 있다면 좋을 것 경우 (질문의 간단한 코드에서) 정확히 페이지 로딩 상태에 해당합니다. 내가 배운 것을 보면 첫 번째 반복 제목에서 url과 동일하고 세 번째 반복에서 올바른 페이지 제목이 표시되었습니다. 그러나 리디렉션하는 동안 onChange는 5 번까지 호출되었습니다. 그래서 어떤 반복이 어떤 단계에 응시 하는지를 확인할 수 있습니까?

0

히스토리가 업데이트되는 정확한 방법은 당신이 의존하고 싶지 않은 구현 세부 사항입니다. 업데이트가 완료되었는지 또는 다양한 필드의 값을 기반으로하지 않았는지 추측하기보다는, onChange(..)이 호출 될 때마다 타이머를 다시 시작하는 것이 좋습니다. 타이머가 만료되면 기록 갱신이 확실하게 가능할 수 있습니다. 타이머를 사용하는 방법

편집 예 :

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

그게 좋은 접근법이고 시도했지만 작동하지 않았습니다.1) 역사가 끝나면 추측은 까다로울 수 있습니다. 사용자가 페이지를로드하는 동안 인터넷 연결이 끊어지면 제목이 URL과 동일하게됩니다 (내 실제 관찰에 기반한 것임). 2) 어떻게 구현할 것을 제안합니까? 'onChange()'는 모든 URL로드에 대해 5 번 호출되므로 원하는 결과를 얻지 못하기 때문에 일시 중지 할 수 없습니다. – anon

+0

그리고 역사가 어떻게 바뀌 었는지 정확히 알 수 있다면, 감사 할 것입니다. (당연한 현상금은 당신 것입니다.) – anon

+0

타이머를 구현하는 방법의 예제 코드로 업데이트했습니다. –

1

은 내가 답을 찾을 수 있습니다 생각합니다. 처음에는 영어가 제한적이라고 말하고 싶습니다. 당신이 저를 이해할 수 있기를 바랍니다.

실제로, onChange();은 기록의 각 변경 사항에 대해 적어도 두 번 이상 실행됩니다.

사용자가 브라우저를 사용하여 웹 사이트를 탐색 할 때 시스템이 데이터베이스에 기록을 추가하고 onChange();이 호출되기 때문입니다. 그러나 지금은 시스템이 URL의 제목을 모른다. 시스템이 URL의 제목을 얻으면 시스템은 데이터베이스를 업데이트하고 onChange();은 두 번째로 호출됩니다.

그리고 URL이 리디렉션되는 경우 시스템에서 새 URL을 가져올 때마다 시스템에서 데이터베이스를 업데이트하므로 onChange(); 너무 불린다. 그래서 나는 onChange가 매번 여러 번 호출 될 것이라고 생각합니다. 희망 당신은 내 영어를 이해할 수 있습니다.