TextDialog.java中onTextChanged函數的解析

來源:互聯網
上載者:User

這幾天在尋找android  browser的一個bug時,發現這個函數停經典的,趕緊記錄下來,呵呵。

這裡我們以IME在www.google.com網頁的輸入框(TextDialog view)中輸入“弟弟ff”為例,首先假設已經輸入了“ff”。

為了輸入“弟弟”,使用者在IME的軟鍵盤上敲d字元兩次,然後“dd”會被聯想為“弟弟”,然後使用者在IME的備選框中選擇聯想得到的“弟弟”。 "dd"到“弟弟”這個步驟會導致如下函數被調用:

onTextChanged(CharSequence s,int start,int before,int count)

//參數s為“弟弟ff”     before為2,表示有兩個字元(“dd”)被刪掉了  count為 2,表示有兩個字元(“弟弟”)被添加了。

//before和count的含義在TextView(cupcake/frameworks/base/core/java/android/widget/TextView.java)的//onTextChanged函數中有注釋。

 

下面把這個函數代碼列出來並附加一點注釋

cupcake/frameworks/base/core/java/android/webkit/TextDialog.java:

protected void onTextChanged(CharSequence s,int start,int before,int count){
        super.onTextChanged(s, start, before, count);
        String postChange = s.toString();         //postChange為“弟弟ff”
        // Prevent calls to setText from invoking onTextChanged (since this will
        // mean we are on a different textfield).  Also prevent the change when
        // going from a textfield with a string of text to one with a smaller
        // limit on text length from registering the onTextChanged event.
        if (mPreChange == null || mPreChange.equals(postChange) ||
                (mMaxLength > -1 && mPreChange.length() > mMaxLength &&
                mPreChange.substring(0, mMaxLength).equals(postChange))) {
            return;
        }
        mPreChange = postChange;    //mPreChange之前的值為"ddff"
        // This was simply a delete or a cut, so just delete the
        // selection.

        //這段代碼不會執行,它用來處理刪除和剪下的。 請注意:在android browser中有一個資料結構render tree來     

        //表示資料,我們需要更新它,同時還有一個CachedText來表示TextDialog中的資料,兩個都需要更新。             

        //mWebView.deleteSelection(start, start + before)代碼更新了render tree這種底層資料, 而   

        //updateCachedTextfield();代碼更新了cached text。
        if (before > 0 && 0 == count) {
            mWebView.deleteSelection(start, start + before);
            // For this and all changes to the text, update our cache
            updateCachedTextfield();
            return;
        }
        // Find the last character being replaced.  If it can be represented by
        // events, we will pass them to native (after replacing the beginning
        // of the changed text), so we can see javascript events.
        // Otherwise, replace the text being changed (including the last
        // character) in the textfield.
        //這段注釋很好,“弟弟”中的最後一個字元“弟”不會從kmap中得到KeyEvent,所以(cannotUseKeyEvents=0)

        //會直接調用mWebView.replaceTextfieldText()(更新browser下層的表示TextDialog的節點的string)把“dd”

        //替換為“dd”,同時updateCachedTextfield()被調用去更新cachedtext.因為“弟”不能被映射為一個KeyEvent,

        //所以  sendDomEvent(events[i])不會調用,沒有event被送給webkit中javascript部分。
        TextUtils.getChars(s, start + count - 1, start + count, mCharacter, 0);
        KeyCharacterMap kmap =
                KeyCharacterMap.load(KeyCharacterMap.BUILT_IN_KEYBOARD);
        KeyEvent[] events = kmap.getEvents(mCharacter);
        boolean cannotUseKeyEvents = null == events;
        int charactersFromKeyEvents = cannotUseKeyEvents ? 0 : 1;
        if (count > 1 || cannotUseKeyEvents) {
            String replace = s.subSequence(start,
                    start + count - charactersFromKeyEvents).toString();
            mWebView.replaceTextfieldText(start, start + before, replace,
                    start + count - charactersFromKeyEvents,
                    start + count - charactersFromKeyEvents);   //在browser底層“dd”替換為“弟弟”
        } else {
            // This corrects the selection which may have been affected by the
            // trackball or auto-correct.
            mWebView.setSelection(start, start + before);
        }
        updateCachedTextfield();   //把cached text中“dd”替換為“弟弟”
        if (cannotUseKeyEvents) {
            return;
        }
        int length = events.length;
        for (int i = 0; i < length; i++) {
            // We never send modifier keys to native code so don't send them
            // here either.
            if (!KeyEvent.isModifierKey(events[i].getKeyCode())) {
                sendDomEvent(events[i]);
            }
        }
    }

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.