Android WebView FindAll does not work in ICE_CREAM_SANDWICH_MR1 and below

Source: Internet
Author: User
Tags string find

The Android system has been developed by everyone regardless of the framework above or native, we will encounter different versions of the Android version of the problem, deprecate the word framework layer contact more children's shoes met quite a lot, Even some APIs will have some bugs. I summarize the personal experience of Android development for different versions of the issue:

1. First look at the official documents and the framework source code, here is recommended a Web site to view the Android system version of the source http://grepcode.com/project/repository.grepcode.com/java/ Ext/com.google.android/android

2. Exclude Project Engineering reasons, you can create a new Android app to use alone, to confirm whether it is the cause of the project factory

3. Eliminate the Android system ROM problem, can find different ROM test results

4. If you have similar products using the same system API, see if other similar products will work properly.

5. Read the source to find out the real cause of the problem, whether it is an API bug,

(1) If Android API Bug View system source framework & native solve the problem.

(2) Refer to similar products, or system application implementation code (specific way no longer elaborate on this side)

Here are some examples of problems I have encountered.

Web Lookup features Android system provides findall this interface, from official documents to see this interface only applies to API level 161 under FINDALL,API level 16 and above using Findallsync.

The problem is that API level 161 is lowered using the text found in the FindAll Web page and is not highlighted.

1. First view Official document HTTP://DEVELOPER.ANDROID.COM/REFERENCE/ANDROID/WEBKIT/WEBVIEW.HTML#FINDALL (java.lang.String)

Confirm that the interface is not effective at API level 161, API 16 and above are used Findallsync our code needs to do such processing.

2. Conclusion Direct call FindAll is not good, create a new project to achieve a simple findall and at the API level model testing.

3. Conclusion The second step is not work, and then look for other models using the same Android version, more than a few sets of basic can determine the problem.

4. Conclusion The third step does not work, and then see if other similar products have the same functional problems.

5. Conclusion The fourth step finds that similar other apps can work properly and can highlight the selected text.

The above analysis can determine the API has a bug, but you can be sure that the bug is solvable.

I use the fifth article to study the framework & native source resolution.

The analysis is as follows:

From Android WebView see provide an API Showfinddialog Showfinddialog Showfinddialog

<span Style= "FONT-SIZE:18PX;" >public Boolean Showfinddialog (String text, Boolean showime) Added in API level 11This method is deprecated in API Lev El 18.This method does reliably on all Android versions; Implementing a custom Find dialog using Webview.findallasync () provides a more robust solution. Starts an actionmode for finding text on this WebView. Only works if this WebView are attached to the view system. Parameterstextif Non-null, 'll is the initial text to search for. Otherwise, the last String searched for in this WebView would be a used to Start.showimeif true, show the IME, assuming the U Ser would begin typing. If false and text is Non-null, perform a Find all. Returnstrue if the Find dialog is shown, false otherwisepublic void stoploading () </span> 
Although this API is deprecated at Android level, it does not affect our testing on the API 15 machine. It is found that the API provided by the system to implement this function can work normally. It is natural to think of Showfinddialog's internal implementation details in API level 15.

Showfinddialog source code on API level (Android 4.0.3, 4.0.4)

<span style= "FONT-SIZE:18PX;"        > Public boolean showfinddialog (String text, Boolean showime) {checkthread ();        Findactionmodecallback callback = new Findactionmodecallback (mcontext);  if (getParent () = null | | Startactionmode (CALLBACK) = = NULL) {//Could not start ' action mode, so end Find        on page return false;        } mcachedoverlappingactionmodeheight =-1;        Mfindcallback = callback;        Setfindisup (true);//highlight Mfindcallback.setwebview (this);        if (showime) {mfindcallback.showsoftinput ();            } else if (text! = null) {mfindcallback.settext (text);            Mfindcallback.findall ();        return true;        } if (text = = null) {text = Mlastfind;        } if (text! = null) {mfindcallback.settext (text);    } return true; }</span>
from the above code we can see that there is a function findall that we care about, and then we look at the concrete implementation of this findall.

<span Style= "FONT-SIZE:18PX;" > void FindAll () {if (Mwebview = = null) {throw new Assertionerror ("No Webvie        W for Findactionmodecallback::findall ");        } charsequence Find = Medittext.gettext ();            if (0 = = Find.length ()) {mwebview.clearmatches ();            Mmatches.setvisibility (View.gone);        Mmatchesfound = false;            } else {mmatchesfound = true;            Mmatches.setvisibility (view.visible);            Mnumberofmatches = Mwebview.findall (find.tostring ()); if (0 = = mnumberofmatches) {mmatches.settext (mresources.getstring (com.android.inte Rnal.            r.string.no_matches));            } else {updatematchesstring (); }}}</span> 

We can see that in fact his internal implementation is also called WebView's FindAll method. Then why do we call ourselves in a problem? The answer is certainly not just a question of invoking this API, as we previously created the project separately and called the FindAll method in the UI main thread without taking effect. Perhaps we will guess whether there is no call to the Invalidate method, through the framework source we see that the WebView FindAll method has called invalidate this method to redraw our UI.

<span style= "FONT-SIZE:18PX;" > Public    int findAll (String find) {        checkthread ();        if (0 = = mnativeclass)            return 0;//client isn ' t initialized        int result = find! = null? Nativefindall (Find.tolowe Rcase (),                find.touppercase (), Find.equalsignorecase (mlastfind)): 0;        Invalidate ();        Mlastfind = find;        return result;    } </span>

So why does showfinddialog internal processing work properly?

We look back at the implementation of the Showfinddialog, the code in the preceding source Setfindisup, this is the whole key.

Our own implementation of the difference and webview internal implementation of the biggest difference is this function, the following we look at the implementation of Setfindisup source code:

<span style= "FONT-SIZE:18PX;" >    private void Setfindisup (Boolean isUp) {        mfindisup = isUp;        if (0 = = Mnativeclass)            return;//client isn ' t initialized        Nativesetfindisup (isUp);    } </span>

The function is to trigger that the kernel is currently looking for state WebView.cpp.

<span style= "FONT-SIZE:18PX;" >    void Setfindisup (bool up)    {        dbg_nav_logd ("up=%d", up);        M_viewimpl->m_findisup = up;    } </span>

The moment of excitement comes, and we are eager to call this API to see if we can really work. The previous Setfindisup method is private.

Java reflect can be handy at this time. We trigger this API before calling FindAll. The following is the reflection implementation code:

<span style= "FONT-SIZE:18PX;" > Public   void Tooglesetfindisup (WebView WebView) {        try {for            (Method m: WebView.class.getDeclaredMethods ()) {                if (M.getname (). Equals ("Setfindisup")) {                    m.setaccessible (true);                    M.invoke ((WebView), true);                    Break;}}}        catch (Exception e) {            e.printstacktrace ();        }    } </span>
we call this method before or after findall to test whether work is possible.

------------------------

------------------------

-----------------------

It works. Show highlight in webpage.


Reprint please specify the source http://blog.csdn.net/typename/article/details/34529859

Thank you!


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

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.