Why use WebView
With the continuous development of APP business, it is not realistic to build functions only by relying on native code. After all, the development time will increase, and both iOS and Android need to be developed at the same time. In addition, if the UI is changed a little bit, it needs to be carried out (although Android can be hot updated now, But hot update is not 100% effective, the principle of which as long as the people know), finally we will choose to use the native nested H5 way for development, so that we can change the UI at any time, but also unlimited function expansion, and then we will use the Android WebView. This makes us pain and happy control.
Now mobile phones are highly customized, more or less will be modified and added to the system’s native code, the WebView of different mobile phones presents different effects, can be said to be colorful, so I understand the pain of Android developers. Next, I will explain my experience of using WebView in my project. If you don’t like it, don’t spray.
use
At first I thought everyone would add WebView controls directly to the layout file. I did the same at first, just for simplicity, and I didn’t know what the problem would be.
<WebView
android:id="@+id/web_view"
android:layout_width="match_parent"
android:layout_height="match_parent"/>Copy the code
Just add a WebView and there is nothing wrong with it. It can display everything normally. When you open a WebView page repeatedly, you will find that the memory of your application will increase, and it will not decrease after it is destroyed, and clicking GC will not decrease, so you will have a memory leak, and you will find that this is not the correct way to use the WebView, so what is the best way to use it? That is, add them dynamically in your code. Start by declaring a parent layout in the layout file
<LinearLayout
android:id="@+id/web_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:scrollbars="none" />Copy the code
And then in your code, you add the WebView as its child View
WebView webView = new WebView(context);
webViewLayout.addView(webView);Copy the code
A lot of people on the web say this context should be an application, which I don’t think is true, but what if your WebView needs to pop up a dialog? There are other unexpected problems, and it is best to use the current activity Context. So that’s how you add a WebView and use it, and then what properties does it have that we need to use in development?
webView.loadUrl("www.baidu.com");//LoadUrl WebSettings WebSettings = webView.getSettings();//Get the WebView set webSettings. SetUseWideViewPort (true);//This property is set, can be arbitrary scaling webSettings. SetLoadWithOverviewMode (true);//Adapter webSettings. SetJavaScriptEnabled (true); //Support js webSettings. SetCacheMode (webSettings. LOAD_DEFAULT);//Set the cache mode webSettings. SetDomStorageEnabled (true);//Open the DOM storage API function webSettings. SetDatabaseEnabled (true);//Open the database storage API function webSettings. SetMixedContentMode (webSettings. MIXED_CONTENT_ALWAYS_ALLOW);//HTTPS, pay attention to this is above the LOLLIPOP just call webSettings setAppCacheEnabled (true);//Open the Application function of Caches webSettings. SetBlockNetworkImage (true);//Turns off loading network images, which can be set to at the beginning of loadingtrueSet to when the page is finished loadingfalseCopy the code
Above is the use of WebView in the most basic Settings, I believe in the development process will carry out the above Settings.
webView.setWebChromeClient(new WebChromeClient() {
@Override
public void onProgressChanged(WebView view, int newProgress) {
// Load progress
}
@Override
public void onReceivedTitle(WebView view, String title) {
// Get the WebView title
}
@Override
public boolean onJsAlert(WebView view, String url, String message, final JsResult result) {
return super.onJsAlert(view, url, message, result);
/ / Js bounced
}
@Override
public boolean onJsConfirm(WebView view, String url, String message, final JsResult result) {
AlertDialog.Builder b = new AlertDialog.Builder(IllegalQueryActivity.this);
b.setTitle("Delete");
b.setMessage(message);
b.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) { result.confirm(); }}); b.setNegativeButton(android.R.string.cancel,new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) { result.cancel(); }}); b.create().show();return true; }}); webView.setWebViewClient(new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
// You need to set the page to display in the current WebView so that it does not jump to the default browser for display
return true;
}
@Override
public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
super.onReceivedError(view, request, error);
// There was a loading error
}
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
// Load complete}}); webView.setDownloadListener(new DownLoadListener());// Download listener
private class DownLoadListener implements DownloadListener {
@Override
public void onDownloadStart(String url, String userAgent, String contentDisposition, String mimetype, long contentLength) {}}Copy the code
Then there’s the WebView and JS interaction
webView.addJavascriptInterface(new WebAppInterface(this), "WebJs");
public class WebAppInterface {
Context mContext;
public WebAppInterface(Context c) {
mContext = c;
}
@JavascriptInterface
public void method(a) {
}
}
webView.loadUrl("javascript:jsMethod()");// This is the simplest way for WebView to call JSCopy the code
When performing the activity lifecycle, it is important to note that the WebView needs to be destroyed during onDestroy, otherwise memory leaks will also occur.
@Overrideprotected void onPause(a) {
super.onPause();
if(webView ! =null) { webView.onPause(); }}@Override
protected void onResume(a) {
super.onResume();
if(webView ! =null) { webView.onResume(); }}@Override
protected void onDestroy(a) {
if(webView ! =null) {
webView.clearCache(true); // Clear the cache
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
if(webViewLayout ! =null) {
webViewLayout.removeView(webView);
}
webView.removeAllViews();
webView.destroy();
}else {
webView.removeAllViews();
webView.destroy();
if(webViewLayout ! =null) {
webViewLayout.removeView(webView);
}
}
webView = null; }}Copy the code
If the parent removes the WebView before destroying it, then the WebView cannot destroy. If the parent removes the WebView before destroying it, the WebView cannot destroy. This will cause a memory leak, so you can try that out for yourself.
Another problem we still encounter is that when WebView is nested in ScrollView, some models will have the problem of flash screen, which will not occur when WebView is alone. After hardware acceleration is turned off, the user experience is not good, so we haven’t come up with a good solution yet. Therefore, it is recommended not to nest controls like WebView in ScrollView. I have summarized so much for the time being. I believe that there will be more problems in the project in the future. If there are other problems, I will update it to make a reminder.