webView的使用(很多坑)
测试环境:Android Studio & Android 9 API 28
完成功能:MainActivity跳转至WebViewActivity,显示目标静态HTML
具体步骤:
-
新建一个 模块/工程
-
主活动布局 activity_main.xml 添加按钮布局:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <Button android:id="@+id/btn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="跳转webView"/> </LinearLayout>
-
修改 MainActivity:
package com.example.webviewtest; //包名自行更改 import android.content.Intent; import android.graphics.Bitmap; import android.os.Build; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.webkit.WebResourceRequest; import android.webkit.WebResourceResponse; import android.webkit.WebSettings; import android.webkit.WebView; import android.webkit.WebViewClient; import android.widget.Button; import android.widget.Toast; import java.io.IOException; import static android.view.View.SCROLLBARS_OUTSIDE_OVERLAY; public class MainActivity extends AppCompatActivity { private Button btn; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main);//加载activity_main布局 btn=(Button)findViewById(R.id.btn); //获取button btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //设置button触发事件 Intent intent=new Intent(MainActivity.this,WebViewActivity.class); String url="http://www.baidu.com"; //设置目标网页地址 intent.putExtra("url",url); startActivity(intent); //intent跳转WebViewActivity finish(); //跳转后退出原活动 } }); } }
-
添加WebView布局 webview_layout.xml :
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <WebView android:id="@+id/webView" android:layout_width="match_parent" android:layout_height="match_parent"> </WebView> </LinearLayout>
-
添加 WebViewActivity :
package com.example.webviewtest; import android.graphics.Bitmap; import android.os.Build; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.webkit.WebResourceRequest; import android.webkit.WebResourceResponse; import android.webkit.WebSettings; import android.webkit.WebView; import android.webkit.WebViewClient; import android.widget.Toast; import java.io.IOException; import static android.view.View.SCROLLBARS_OUTSIDE_OVERLAY; public class WebViewActivity extends AppCompatActivity { private WebView webView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.webview); webView = findViewById(R.id.webView); webView.loadUrl(getIntent().getStringExtra("url"));//提取目标url webView.setWebViewClient(new WebViewClient() { @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { view.loadUrl(url);//使用当前WebView处理跳转 return true;//true表示此事件在此处被处理,不需要再广播 } } }
-
修改 AndroidManifest.xml :
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.webviewtest"><uses-permission android:name="android.permission.INTERNET" /> //打开网络权限,若不设置则断网 <application android:usesCleartextTraffic="true" //使用明文传输,若不设置则无法用http访问网络 android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/Theme.AppCompat.NoActionBar"> //删除标题栏 <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name=".WebViewActivity"></activity> //注册WebViewActivity活动 </application> </manifest>
-
运行结果:
如果访问百度之类的网站,上面已经够了,但如果是访问你自己的服务器,比如tomcat,还要继续下面的操作,否则会出现网络中断、样式加载失败、图片无法加载等问题。
-
添加xml文件夹
-
在xml文件夹新建 network_security_config.xml ,
想了解原因的可以移步 https://blog.csdn.net/lz8362/article/details/78289930
<?xml version="1.0" encoding="utf-8"?> <network-security-config> <base-config cleartextTrafficPermitted="true"> <trust-anchors> <certificates src="system" /> </trust-anchors> </base-config> </network-security-config>
-
修改 AndroidManifest.xml
android:usesCleartextTraffic="true"
替换为
android:networkSecurityConfig="@xml/network_security_config"
-
修改 WebViewActivity ,在 Oncreate() 里添加
WebSettings webSettings = webView.getSettings(); webSettings.setBlockNetworkImage(false); // 解决图片不显示 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { webSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW); //允许混合内容模式 }
这样应该就能显示了,但是加载的速度不尽人意,下面进行一些优化。
1. 添加缓存,修改WebViewActivity,在Oncreate()里继续添加
webSettings.setCacheMode(WebSettings.LOAD_DEFAULT);//加载缓存
想详细了解的可以参考 https://www.jianshu.com/p/6575304281a1 添加缓存后能很明显提高第一次之后启动的加载速度
2. 将 js、css 放到 app 本地加载
按照原来的写法,引入的css和js要么是个http外链,要么是很长很长的样式表,可能一个30k的网页有20k的样式代码。
不管是哪种,在访问或解析数据都消耗了大量时间,如果把固定的样式放在本地加载,速度会有质的飞跃
如果你的html文件恰好都是同一种样式,比如说bootstrap等等,那就更适合用这种方法了 _
-
首先,在工程里添加assets文件夹,用于存放样式文件
-
把你的样式文件放入assets文件夹里,比如说 passage.css,修改你的html样式为外链,比如:
<link rel="stylesheet" href="passage.css" type="text/css" />
- 修改WebViewActivity,重写Oncreate()里setWebViewClient()的shouldInterceptRequest()方法,你可以在setWebViewClient方法体内按 Ctrl+o 找到它
webView.setWebViewClient(new WebViewClient() { //在app内部打开网页
@Override
public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
WebResourceResponse response = null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
response = super.shouldInterceptRequest(view, request);
if (request.getUrl().toString().contains("passage.css")) { //监听请求地址,如果请求的是 样式文件passage.css
try { //重写response,修改请求头,按utf-8编码,加载本地样式
response = new WebResourceResponse("text/css", "UTF-8", getAssets().open("passage.css"));
} catch (IOException e) { //getAssets().open(String file):按字符串在assets资源文件夹里查找文件
e.printStackTrace();
}
}
}
return response;
}
}
- 如果是 js 文件,还要在Oncreate()里添加:
webSettings.setJavaScriptEnabled(true);
默认WebView还有一个滚动条,可以进行隐藏,更有原生体验效果
- 在Oncreate()里添加
webView.setHorizontalScrollBarEnabled(false);
webView.setVerticalScrollBarEnabled(false);
看看效果,很不错吧 _
转载请注明博文来源,有什么问题欢迎在评论栏留言。 ——Kevin_Lu 2020-03-02