2013-05-20 33 views
5

Tôi đã triển khai người quan sát nội dung lịch sử nhưng nó hoạt động lạ. Đối với mọi thay đổi trong lịch sử, hàm onChange() của nó chạy 3-5 lần.Trình theo dõi nội dung lịch sử Android

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

} 

Tôi cũng đăng ký quan sát của tôi sử dụng

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

và bổ sung quyền yêu cầu trong biểu hiện.

Mã hoạt động tốt nhưng onChange(); chạy 3-5 lần cho mỗi thay đổi trong lịch sử
Có ai có thể giúp tôi giải quyết vấn đề này không?

+4

http://stackoverflow.com/questions/6026547/android-content-observers-onchange-method-is-called-multiple-times không giúp ích gì cho tôi. – anon

+3

Điều tôi quan sát được là sự khác biệt giữa lần chạy thứ nhất và thứ ba là: Trong tiêu đề chạy đầu tiên giống như url nhưng trong lần chạy thứ ba, tiêu đề phù hợp xuất hiện. Vì vậy, nó có thể là do các giai đoạn các trang được nạp vào. Nhưng chính xác thì nó là gì? Và tại sao số lần chạy lại khác nhau? – anon

+0

xin vui lòng để lại một bình luận nếu bạn cần thêm thông tin – anon

Trả lời

2

Đây là cách cuối cùng tôi giải quyết được vấn đề đối với trường hợp ít nhất của tôi (tôi muốn đọc lịch sử khi có sự thay đổi trong lịch sử)

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

Nhưng vẫn nếu sẽ là tuyệt vời nếu ai đó có thể nói đó lặp đi lặp lại của onChange (trong mã câu hỏi đơn giản) tương ứng với chính xác trạng thái tải trang nào. Từ những gì tôi đã học được, trong tiêu đề lặp lại đầu tiên giống như url và trong lần lặp thứ ba, tiêu đề trang chính xác đã xuất hiện. Nhưng trong quá trình chuyển hướng, onChange được gọi tối đa 5 lần. Vì vậy, ai đó có thể xác nhận lặp đi lặp lại coressponds đến giai đoạn nào?

0

Cách chính xác mà lịch sử được cập nhật là chi tiết triển khai mà bạn có thể không muốn dựa vào. Thay vì cố gắng đoán xem bản cập nhật có hoàn thành hay không dựa trên các giá trị của các trường khác nhau, tôi khuyên bạn nên khởi động lại bộ hẹn giờ mỗi lần gọi onChange(..). Nếu bộ đếm thời gian hết hạn, bạn có thể chắc chắn rằng lịch sử đã hoàn tất cập nhật.

Sửa Ví dụ về cách sử dụng một bộ đếm thời gian:

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

Vâng đó là một cách tiếp cận tốt đẹp quá và tôi đã thử nó, nhưng nó đã không làm việc.1) Đoán khi lịch sử đã hoàn thành cập nhật có thể được khôn lanh quá. Giả sử người dùng mất kết nối internet trong khi tải trang, điều đó sẽ khiến tiêu đề giống với url (dựa trên quan sát thực tế của tôi). 2) Bạn đề xuất thế nào để thực hiện nó? 'onChange()' sẽ được gọi là 5 lần cho mỗi tải url, vì vậy bạn không thể tạm dừng nó vì điều đó sẽ không cho kết quả mong muốn. – anon

+0

Và nếu bạn có thể cho tôi biết cách chính xác trong đó lịch sử được cập nhật, tôi sẽ biết ơn (ofcourse tiền thưởng là của bạn quá sau đó). – anon

+0

được cập nhật với mã ví dụ về cách triển khai bộ hẹn giờ như vậy –

1

Tôi nghĩ rằng tôi có thể tìm thấy câu trả lời. Đầu tiên tôi muốn nói rằng tiếng Anh của tôi bị giới hạn, tôi hy vọng rằng bạn có thể hiểu tôi.

Thực tế, onChange(); chạy nhiều lần cho mỗi thay đổi trong lịch sử, ít nhất hai lần.

Bởi vì khi người dùng sử dụng trình duyệt để duyệt một trang web, hệ thống sẽ thêm lịch sử vào cơ sở dữ liệu và onChange(); được gọi. Nhưng ngay bây giờ hệ thống không biết tiêu đề của url. Sau khi hệ thống nhận được tiêu đề của url, hệ thống cập nhật cơ sở dữ liệu và onChange(); được gọi là lần thứ hai.

Và nếu url chuyển hướng trong thời gian, mỗi khi hệ thống nhận được url mới, hệ thống cũng sẽ cập nhật cơ sở dữ liệu, vì vậy onChange(); được gọi là quá. Vì vậy, tôi nghĩ onChange sẽ được gọi nhiều lần mỗi lần thay đổi. Hy vọng bạn có thể hiểu tiếng Anh của tôi.