Use of WebView -- Part 1

Keywords: Android html5 Mobile encoding

I. Combing Knowledge

1. Preface

This section brings you a control in Android for displaying web pages: WebView.

Now there are two directions for Android application layer development: client development and HTML5 mobile development!

The so-called HTML5 end is: HTML5 + CSS + JS to build a web page version of the application, and the intermediary is this WebView, and the Web and Web can interact through JS, for example, web pages to read mobile phone contacts, call mobile phone related API s, etc.

And HTML5 Mobile has an advantage over ordinary client development: it can be used as a percentage of layout, and if HTML5 has any major changes, we don't have to go back to the next APP like the client, and then override the installation, we just need to modify the next page! And the client.... Unfortunately, HTML5 also has a drawback, that is, performance issues, data accumulation, power consumption issues, and flash screens and so on.

In addition, for this cross-platform, we can use other third-party rapid development frameworks, such as PhoneGap, by the way, there are many websites that generate APP class with one click on the network. Users can generate an application through simple operations such as dragging, setting pictures and so on. Most of them are done with HTML5! There are templates, direct sets, you know ~well, don't say much, start this section!

2. What is WebView?

Answer: Android has built-in high-performance browser with webkit kernel, and WebView is a control encapsulated on this basis. WebView translates Web View literally. We can simply regard it as a browser control that can be nested on the interface!

3. Relevant methods

First, the official documents: WebView It's not intended to talk about attributes one by one, which to write, and other self-referencing documents! In addition to direct WebView, we can also add your own behavior, you can customize the following categories: see the documentation for details: (to turn over the wall)

http://androiddoc.qiniudn.com/reference/android/webkit/WebView.html

WebChromeClient: Help WebView process Javascript dialog boxes, website icons, website title, loading progress, etc. For example, the following:

Method Effect
onJsAlert(WebView view,String url,String message,JsResult result) Processing alert dialog box in JS
onJsConfirm(WebView view,String url,String message,JsResult result) Processing the confirm at dialog box in JS
onJsPrompt(WebView view,String url,String message,String defaultValue,JsPromptResult result) Processing Prompt Dialogue Box in JS
onProgressChanged(WebView view,int newProgress) Callback when the progress of loading progress bar changes
onReceivedIcon(WebView view, Bitmap icon) Get the icon of the web page
onReceivedTitle(WebView view, String title) Get the title of the page

WebViewClient: Helps WebView handle various notification and request events! For example, the following methods:

onPageStared(WebView view,String url) Notify the main program that the page has started loading.
onPageFinished(WebView view,String url,Bitmap favicon) Notify the main program that the page is loaded.
doUpdateVisitedHistory(WebView view,String url,boolean isReload) Update history
onLoadResource(WebView view,String url) Notify the main program that the URL of the specified resource is about to load
onScaleChanged(WebView view,float oldScale,float newScale) Called when a change occurs during WebView zooming
shouldOverrideKeyEvent(WebView view,KeyEvent event) Controls whether WebView handles keystroke events and returns true, WebView does not handle them, and WebView handles them if it returns false.
shouldOverrideUrlLoading(WebView view,String url) Controlling the processing of newly loaded Url and returning true indicates that the main program does not process WebView and returning false means that WebView will process it.
onReceivedError(WebView view,int errorCode,String description,String failingUrl) Processing the returned error information
Method Effect

WebSettings: Settings for WebView-related configurations, such as setJavaScript Enabled () settings, allow JS script execution as follows:

Method Effect
getSettings() Returns a WebSettings object to control the property settings of WebView
loadUrl(String url)
Load the specified Url
loadData(String data,String mimeType,String encoding) Load the specified data into WebView. Using "data:" as the tag header, this method cannot load network data. The mimeType is the encoding method of characters such as textml,image/jpeg. encoding.
loadDataWithBaseURL(String baseUrl, String data, String mimeType, String encoding, String historyUrl) More powerful than the loadData above
setWebViewClient(WebViewClient client) Specify a WebViewClient object for WebView. WebViewClient can assist WebView in handling various notifications, requests, and other events.
setWebChromeClient(WebChromeClient client) Specify a WebChromeClient object for WebView. WebChromeClient is designed to assist WebView in handling js dialog boxes, website title, website icons, loading progress bars, etc.

It is important to distinguish the three load methods here:

  • loadUrl(): Display the content of the web page directly (display the network picture separately), generally without scrambling code.
  • Load Data (data,'text/html','UTF-8'): Used to load URI format data, can't load content through the network, can't load pictures, and often encounter scrambling problems. We know that String type data is mainly Unicode encoding, while WebView generally uses UTF-8 encoding to save resources, although we wrote above, but also need to set up for webView. Set: webview. getSettings (). setDefaultTextEncoding Name ("UTF-8")
  • LoadDataWithBaseURL (baseUrl, string,'text/html','utf-8', null): An enhancement class of loadData class that can load pictures, baseUrl stores image paths for you, and just set UTF-8 here to solve the scrambling problem.

Web Chrome Client

http://androiddoc.qiniudn.com/reference/android/webkit/WebChromeClient.html

WebViewClient document

http://androiddoc.qiniudn.com/reference/android/webkit/WebViewClient.html

Web Setting Paper

http://androiddoc.qiniudn.com/reference/android/webkit/WebSettings.html

II. Practical application

public class MainActivity extends AppCompatActivity {

    private WebView webView;
    private long exitTime = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        webView = new WebView(this);
        webView.setWebViewClient(new WebViewClient() {
            //Set the new web page opened by clicking on webView to display in the current interface without jumping to the new browser
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                view.loadUrl(url);
                return true;
            }
        });
        webView.getSettings().setJavaScriptEnabled(true);  //Set WebView properties and run the js script
        webView.loadUrl("http://www.baidu.com/";//Call the loadUrl method to add links to WebView
        setContentView(webView);                           //Call the setContentView provided by Activity to display the webView
    }


    //We need to rewrite the time of the Back button when the user clicks the Back button:
    //1.webView.canGoBack() judges whether the page can go backward, and goback()
    //2. If you can't quit App twice in a row, otherwise pop-up prompt Toast
    @Override
    public void onBackPressed() {
        if (webView.canGoBack()) {
            webView.goBack();
        } else {
            if ((System.currentTimeMillis() - exitTime) > 2000) {
                Toast.makeText(getApplicationContext(), "Press the exit procedure again",
                        Toast.LENGTH_SHORT).show();
                exitTime = System.currentTimeMillis();
            } else {
                super.onBackPressed();
            }

        }
    }
}

2) Setting WebView in Layout Code

I believe you have seen a lot of news App bars or portal information apps, his structure may be as follows:

public class MainActivity extends AppCompatActivity implements View.OnClickListener {


    private Button btn_back;
    private TextView txt_title;
    private Button btn_top;
    private Button btn_refresh;
    private WebView wView;
    private long exitTime = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        bindViews();
    }


    private void bindViews() {
        btn_back = (Button) findViewById(R.id.btn_back);
        txt_title = (TextView) findViewById(R.id.txt_title);
        btn_top = (Button) findViewById(R.id.btn_top);
        btn_refresh = (Button) findViewById(R.id.btn_refresh);
        wView = (WebView) findViewById(R.id.wView);

        btn_back.setOnClickListener(this);
        btn_refresh.setOnClickListener(this);
        btn_top.setOnClickListener(this);

        wView.loadUrl("http://www.baidu.com");
        wView.setWebChromeClient(new WebChromeClient() {
            //Set the title of the acquired website here
            @Override
            public void onReceivedTitle(WebView view, String title) {
                super.onReceivedTitle(view, title);
                txt_title.setText(title);
            }
        });


        wView.setWebViewClient(new WebViewClient() {
            //Open new links in webview
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                view.loadUrl(url);
                return true;
            }
        });
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btn_back:
                finish();          //Close the current Activity
                break;
            case R.id.btn_refresh:
                wView.reload();    //Refresh
                break;
            case R.id.btn_top:
                wView.setScrollY(0);   //Scroll to the top
                break;
        }
    }
    
    @Override
    public void onBackPressed() {
        if (wView.canGoBack()) {
            wView.goBack();
        } else {
            if ((System.currentTimeMillis() - exitTime) > 2000) {
                Toast.makeText(getApplicationContext(), "Press the exit procedure again",
                        Toast.LENGTH_SHORT).show();
                exitTime = System.currentTimeMillis();
            } else {
                finish();
            }

        }
    }
}

Question Answer:

Believe careful friends to see, we go back to the page loaded at the beginning, press the return key, press the return key many times or did not exit the current APP, or later we manually click the back key to close the current Activity by calling the finish method? Why? Mingming Baidu is already the first page?

Answer: Actually, the reason for this is: the redirection problem of the website caused, in fact, when we visited Baidu:

Although we load ed www.baidu.com, Baidu redirected and jumped to the mobile version of Baidu's website: that is, the actual process is: www.baidu.com-> mobile version of Baidu - > open other links!

We see that the shouldOverrideUrlLoading() method we wrote above is as follows:

view.loadUrl(url);return true; we know that when a user clicks the back button, WebView calls a goback method (). We set the three above sites as A, B and C, back at C, C - > B is no problem, and then B - > A. At this time, the problem comes even though B arrives at A, but because redirection jumps to B again, so the cycle goes back and forth. What's the reason why clicking the Back button didn't launch WebView? Solution: Hand speed, double-click the Back button continuously when the WebView is not loaded. Hand speed is fast enough, haha! Just kidding, to solve this problem, we just need to delete the "should Override Url Loading" and write "return false"; If you don't believe it's redirection, you can try modifying the URL yourself.~

Requirement 2: Monitoring of WebView Scroll Events

We all know that listening for scrolling events is usually set on ScrollChangedListener. Unfortunately, WebView does not provide us with such a method, but we can rewrite WebView to cover one of its methods: protected void onScrollChanged (final int, final int oldl, final int oldt){} and then provide an interface to the outside world, such as sample code. Next:

/**
 * Created by Jay on 2015/9/11 0011.
 */
public class MyWebView extends WebView {

    private OnScrollChangedCallback mOnScrollChangedCallback;

    public MyWebView(Context context) {
        super(context);
    }

    public MyWebView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public MyWebView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    protected void onScrollChanged(int l, int t, int oldl, int oldt) {
        super.onScrollChanged(l, t, oldl, oldt);
        if (mOnScrollChangedCallback != null) {
            mOnScrollChangedCallback.onScroll(l - oldl, t - oldt);
        }
    }

    public OnScrollChangedCallback getOnScrollChangedCallback() {
        return mOnScrollChangedCallback;
    }

    public void setOnScrollChangedCallback(
            final OnScrollChangedCallback onScrollChangedCallback) {
        mOnScrollChangedCallback = onScrollChangedCallback;
    }

    public static interface OnScrollChangedCallback {
        //Here dx and dy represent offsets on the x and y axes. You can also expose the four parameters of l, t, oldl and oldt by yourself.
        public void onScroll(int dx, int dy);
    }

}
public class MainActivity extends AppCompatActivity {

    private MyWebView wView;
    private Button btn_icon;
    private long exitTime = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        btn_icon = (Button) findViewById(R.id.btn_icon);
        wView = (MyWebView) findViewById(R.id.wView);
        wView.loadUrl("http://www.hao123.com");
        wView.setWebViewClient(new WebViewClient() {
            //Open new links in webview
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                view.loadUrl(url);
                return true;
            }
        });

        //For example, let's make a simple judgment here. When the page scrolls, it shows the Button.
        wView.setOnScrollChangedCallback(new MyWebView.OnScrollChangedCallback() {
            @Override
            public void onScroll(int dx, int dy) {
                if (dy > 0) {
                    btn_icon.setVisibility(View.VISIBLE);
                } else {
                    btn_icon.setVisibility(View.GONE);
                }
            }
        });

        btn_icon.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                wView.setScrollY(0);
                btn_icon.setVisibility(View.GONE);
            }
        });

    }

    @Override
    public void onBackPressed() {
        if (wView.canGoBack()) {
            wView.goBack();
        } else {
            if ((System.currentTimeMillis() - exitTime) > 2000) {
                Toast.makeText(getApplicationContext(), "Press the exit procedure again",
                        Toast.LENGTH_SHORT).show();
                exitTime = System.currentTimeMillis();
            } else {
                finish();
            }

        }
    }
}

Requirement 3: Scrollbars

The attributes you may use are as follows:

  • SetHorizontal ScrollBarEnabled (false); // Horizontal does not display
  • SetVertical ScrollBar Enabled (false); //Vertical non-display
  • setScrollBarStyle(View.SCROLLBARS_OUTSIDE_OVERLAY); //Scrollbar is displayed inside WebView
  • setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY)// Scrollbar is displayed outside WebView

Requirement 4: Setting up scaling and adaptive screens

According to our general habit of opening webpages for places where we can't see clearly, we like to zoom webpages with two fingers, while WebView needs us to manually set whether this supports zoom or not!

Just add the following code:

WebSettings settings = wView.getSettings();
settings.setUseWideViewPort(true);//Setting support viewport
settings.setLoadWithOverviewMode(true);   //Adaptive Screen
settings.setBuiltInZoomControls(true);
settings.setDisplayZoomControls(false);
settings.setSupportZoom(true);//Setting support for zooming

When we zoom, there is a nauseating problem, that is, the very common zoom control, we certainly do not want it, then add the following sentence code to hide the zoom control!

settings.setDisplayZoomControls(false);

We can also set the initial zoom ratio by ourselves, just for webView:

WView.setInitial Scale (25); //25%, minimum zoom level

Hey hey, the whole page is zoomed in, but maybe sometimes we just need to zoom in the font, so we can do this:

settings.setTextZoom(int);

It can also be directly through:

settings.setTextSize(TextSize.LARGER);

To set the size.

The size of the 5 fonts that Android comes with:

SMALLEST(50%),SMALLER(75%),NORMAL(100%),LARGER(150%), LARGEST(200%).

Requirement 5. Getting Cookie data for WebView

We all know that Cookie is actually a string representing the unique identity of the user. The general situation is: after the user enters the password of the account, click on the login, the user will take this Cookie to access the relevant services provided by the server! We can write cookie acquisition into onPageFinsihed's method, which can be simply written as follows:

@Override
public void onPageFinished(WebView view, String url) {             
    CookieManager cookieManager = CookieManager.getInstance();
    String CookieStr = cookieManager.getCookie(url);
    Log.e("HEHE", "Cookies = " + CookieStr);
    super.onPageFinished(view, url);
}

Requirement 6. Setting up Cookie data for WebView

Hey hey, we got Cookies up there or through other means, how do we set up Cookies for WebView? We can add the following code where we need to set up cookies:

CookieSyncManager.createInstance(MainActivity.this);  
CookieManager cookieManager = CookieManager.getInstance();  
cookieManager.setAcceptCookie(true);  
cookieManager.setCookie(url, cookies);  //cookies are cookie strings to set 
CookieSyncManager.getInstance().sync();

By the way, the above code needs to be written before loadUrl(), and if you set up Cookie, try not to make other settings, otherwise it may be invalid. It is recommended that cookies be written at the end of the webView settings ~loadUrl()!

Posted by NotMrT on Mon, 24 Jun 2019 16:49:04 -0700