It’s not easy for WebView to say I love you

It’s not easy for WebView to say I love you

[[189802]]

Why use WebView?

With the continuous development of app business, it is unrealistic to rely solely on native code to pile up functions. After all, the development time will increase, and both iOS and Android need to be developed at the same time. Moreover, if the UI is changed a little bit, a package needs to be moved (although Android can now perform hot updates, hot updates are not 100% effective. Anyone who has understood the principle will know it). In the end, we will choose to use native nested H5 for development. In this way, we can change the UI at any time and expand functions arbitrarily. Then, we will use Android's WebView, the control that makes us both sad and happy.

Nowadays, mobile phones are highly customized, and the native code of the system will be modified and added to a certain extent. The effects presented by WebView of different mobile phones are also different, which can be said to be colorful, so I understand the pain of Android developers. Next, I will explain my experience of using WebView in the project in detail. If you don't like it, please don't criticize me.

use

At the beginning, I believe everyone added the WebView control directly to the layout file. Of course, I did the same at the beginning, just for simplicity, and I didn’t know what problems would arise.

  1. <WebView
  2.  
  3. android:id= "@+id/web_view"      
  4.  
  5. android:layout_width= "match_parent"      
  6.  
  7. android:layout_height= "match_parent" />

Just add a WebView like this, and you will find that there is no problem, it can be displayed as usual, and everything is normal. When you repeatedly open the page with WebView, you will find that the memory of the application will continue to increase, and it will not drop after being destroyed, and it will not drop even if you click GC. This is a memory leak. At this time, you will find that it is incorrect to use WebView in this way, so what is the best way to use it?

That is to add it dynamically in the code.

First, declare a parent layout in the layout file

  1. <LinearLayout
  2.  
  3. android:id= "@+id/web_view"  
  4.  
  5. android:layout_width= "match_parent"  
  6.  
  7. android:layout_height= "wrap_content"  
  8.  
  9. android:orientation= "horizontal"  
  10.  
  11. android:scrollbars= "none" />

Then in the code, add WebView as its child View

  1. WebView webView = new WebView(context);
  2.  
  3. webViewLayout.addView(webView);

Many people on the Internet say that this context should use the application. I think it is wrong. What if your WebView needs to pop up a dialog? There are other unpredictable problems. It is best to use the Context of the current activity.

The above is about how to add WebView for use, and then what properties of it do we need to use in development?

  1. webView.loadUrl( "www.baidu.com" ); //WebView loads the webpage using loadUrl
  2.  
  3. WebSettings webSettings = webView.getSettings(); //Get WebView settings
  4.  
  5. webSettings.setUseWideViewPort( true ); // Set this property to scale at any ratio
  6.  
  7. webSettings.setLoadWithOverviewMode( true );//Adaptation
  8.  
  9. webSettings.setJavaScriptEnabled( true ); //Support js
  10.  
  11. webSettings.setCacheMode(WebSettings.LOAD_DEFAULT); //Set cache mode
  12.  
  13. webSettings.setDomStorageEnabled( true ); // Enable DOM storage API function
  14.  
  15. webSettings.setDatabaseEnabled( true ); // Enable database storage API function
  16.  
  17. webSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW); //HTTPS, note that this is called above LOLLIPOP
  18.  
  19. webSettings.setAppCacheEnabled( true ); // Enable Application Caches
  20.  
  21. webSettings.setBlockNetworkImage( true ); //Turn off loading network images. Set this to true at the beginning of loading , and set it to false when the web page is finished loading.  

The above are the most basic settings for using WebView. I believe that the above settings will be performed during the development process.

  1. webView.setWebChromeClient(new WebChromeClient() {
  2.  
  3. @Override
  4.  
  5. public void onProgressChanged(WebView view , int newProgress) {
  6.  
  7. //Loading progress
  8.  
  9. }
  10.  
  11. @Override
  12.  
  13. public void onReceivedTitle(WebView view , String title) {
  14.  
  15. //Get the title of the WebView
  16.  
  17. }
  18.  
  19. @Override
  20.  
  21. public boolean onJsAlert(WebView view , String url, String message, final JsResult result) {
  22.  
  23. return super.onJsAlert( view , url, message, result);
  24.  
  25. //Js pop-up box
  26.  
  27. }
  28.  
  29. @Override
  30.  
  31. public boolean onJsConfirm(WebView view , String url, String message, final JsResult result) {
  32.  
  33. AlertDialog.Builder b = new AlertDialog.Builder(IllegalQueryActivity.this);
  34.  
  35. b.setTitle( "Delete" );
  36.  
  37. b.setMessage(message);
  38.  
  39. b.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
  40.  
  41. @Override
  42.  
  43. public void onClick(DialogInterface dialog, int which) {
  44.  
  45. result.confirm();
  46.  
  47. }
  48.  
  49. });
  50.  
  51. b.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
  52.  
  53. @Override
  54.  
  55. public void onClick(DialogInterface dialog, int which) {
  56.  
  57. result.cancel();
  58.  
  59. }
  60.  
  61. });
  62.  
  63. b.create ().show();
  64.  
  65. return   true ;
  66.  
  67. }
  68.  
  69. });
  70.  
  71. webView.setWebViewClient(new WebViewClient() {
  72.  
  73. @Override
  74.  
  75. public boolean shouldOverrideUrlLoading(WebView view , String url) {
  76.  
  77. //You need to set the web page to be displayed in the current WebView so that it will not jump to the default browser for display
  78.  
  79. return   true ;
  80.  
  81. }
  82.  
  83. @Override
  84.  
  85. public void onReceivedError(WebView view , WebResourceRequest request, WebResourceError error) {
  86.  
  87. super.onReceivedError( view , request, error);
  88.  
  89. //Loading error
  90.  
  91. }
  92.  
  93. @Override
  94.  
  95. public void onPageFinished(WebView view , String url) {
  96.  
  97. super.onPageFinished( view , url);
  98.  
  99. //Loading completed
  100.  
  101. }
  102.  
  103. });
  104.  
  105. webView.setDownloadListener(new DownLoadListener()); //Download listener
  106.  
  107. private class DownLoadListener implements DownloadListener {
  108.  
  109. @Override
  110.  
  111. public void onDownloadStart(String url, String userAgent, String contentDisposition, String mimetype, long contentLength) {
  112.  
  113. }
  114.  
  115. }

Then there is the interaction between WebView and JS

  1. webView.addJavascriptInterface(new WebAppInterface(this), "WebJs" );
  2.  
  3. public class WebAppInterface {
  4.  
  5. Context mContext;
  6.  
  7. public WebAppInterface(Context c) {
  8.  
  9. mContext = c;
  10.  
  11. }
  12.  
  13. @JavascriptInterface
  14.  
  15. public void method() {
  16.  
  17. }
  18.  
  19. }
  20.  
  21. webView.loadUrl( "javascript:jsMethod()" ); //This is the simplest way to call JS in WebView

When the activity executes the life cycle, it is important to note that WebView needs to be destroyed during onDestroy, otherwise memory leaks will occur.

  1. @Overrideprotected void onPause() {
  2.  
  3. super.onPause();
  4.  
  5. if (webView != null ) {
  6.  
  7. webView.onPause();
  8.  
  9. }
  10.  
  11. }
  12.  
  13. @Override
  14.  
  15. protected void onResume() {
  16.  
  17. super.onResume();
  18.  
  19. if (webView != null ) {
  20.  
  21. webView.onResume();
  22.  
  23. }
  24.  
  25. }
  26.  
  27. @Override
  28.  
  29. protected void onDestroy() {
  30.  
  31. if (webView != null ) {
  32.  
  33. webView.clearCache( true ); // Clear the cache
  34.  
  35. if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
  36.  
  37. if (webViewLayout != null ) {
  38.  
  39. webViewLayout.removeView(webView);
  40.  
  41. }
  42.  
  43. webView.removeAllViews();
  44.  
  45. webView.destroy();
  46.  
  47. } else {
  48.  
  49. webView.removeAllViews();
  50.  
  51. webView.destroy();
  52.  
  53. if (webViewLayout != null ) {
  54.  
  55. webViewLayout.removeView(webView);
  56.  
  57. }
  58.  
  59. }
  60.  
  61. webView = null ;
  62.  
  63. }
  64.  
  65. }

You can see that the system version is judged in the onDestroy method above. That's because I tested it in different versions. If the WebView version is lower than 5.0, if the WebView is removed from the parent first, the WebView will not be destroyed, which will cause memory leaks. You can try it yourself to see if this statement is correct.

Another problem we are facing now is that when WebView is nested in ScrollView, some models will have screen flashing problems, which will not happen when using WebView alone. After turning off hardware acceleration, the user experience is not good. Therefore, we have not thought of a better solution yet, so it is recommended not to nest controls such as WebView in ScrollView.

<<:  Things about memory optimization in Android - a record of image optimization

>>:  Android full set of animation usage tips

Recommend

Review: NetEase Kaola’s Double 11 integrated marketing strategy!

I have been searching for spring for half my life...

Bi Yiming's "12 Rehabilitation Courses for Herniated Disc"

Course Catalog: ├──Section 01 What are the common...

Creative Guide for Information Flow Promotion in Tourism Industry

In the blink of an eye, it is the end of March. T...

How to design a high-conversion training camp from scratch?

I've been receiving a lot of inquiries about ...

Apple iOS 15 Messages App has a bug that causes saved photos to be deleted

September 30 News Messages is a feature update la...

E-commerce operations: traffic source analysis

For e-commerce platforms, accurately identifying ...

5 marketing discoveries in today’s communications environment

01 Brands are losing marketing initiative In the ...

Serious research: Thanos can't perform the snap that saves the universe

Written by: Wu Tingting Editor: Kou Jianchao Layo...

Tencent advertising promotion quantity, time and basic overview!

1.How many ads can one account create? In one acc...

Interpretation of APP visual rules: What are the Gestalt psychology rules!

We often hear some design experts share with us t...

FAQs about VIVO App Store Management

Application Management FAQ Q1. What is the regist...