Android History Content Observer

前端 未结 3 1464
轮回少年
轮回少年 2021-02-10 06:18

I implemented content observer of history but it is behaving weird.For every change in history its onChange() function runs 3-5 times.

static class BrowserOberse         


        
相关标签:
3条回答
  • 2021-02-10 06:58

    This is how I finally solved the problem for my case atleast(I wanted to read history when there is change in history)

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

    But still if would be great if someone could tell which iteration of onChange(in the simple code of question) corresponds to exactly which state in page loading. From what I learned, in first iteration title was same as url and in the third iteration the correct page title was present. But during redirection, onChange got called upto 5 times. So can someone confirm which iteration coressponds to which stage?

    0 讨论(0)
  • 2021-02-10 07:03

    I think I may find the answer. First I want to say that my English is limited, I hope that you can understand me.

    Indeed, onChange(); runs several times for each change in history, at least two times.

    Because when user use the browser to browse a website, the system add a history in database, and onChange(); is called. But right now the system don't know the title of the url. After the system got the title of the url, the system updates the database and onChange(); is called second time.

    And, if the url is redirecting during the time, every time the system gets a new url, the system will update the database too, so onChange(); is called too. So, I think onChange will be called several times every change. Hope you can understand my English.

    0 讨论(0)
  • 2021-02-10 07:19

    The exact way in which history is updated is an implementation detail you probably do not want to be relying on. Rather than trying to guess whether the update is finished or not based on the values of various fields, I would suggest restarting a timer each time onChange(..) is called. If the timer expires, you can be reasonably certain that history has finished updating.

    Edit Example of how to use a timer:

    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");
        }
    
    }
    
    0 讨论(0)
提交回复
热议问题