

安卓WebView相关设置
source link: http://frank-zhu.github.io/android/2015/08/19/android-html5-web-view/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

很久没有更新博客了,也不知道应该更新一些什么,最近刚好在用WebView对接一些接口设置,就写下来记录一下吧,希望能帮到遇到同样问题的人。
一、基本设置
一般WebView不做多余配置,没有交互要求,只是很简单的载入网页的话,基本下面的配置就够用了
WebSettings mWebSettings = mWebView.getSettings();
mWebSettings.setSupportZoom(true);
mWebSettings.setLoadWithOverviewMode(true);
mWebSettings.setUseWideViewPort(true);
mWebSettings.setDefaultTextEncodingName("GBK");
mWebSettings.setLoadsImagesAutomatically(true);
上面可以看到,对于基本的使用,配置是很简单的,没什么太多需要自己注意的,接下来就是一些手机APP上载入网页的时候用得比较多的情况了,下面会一一列出。
二、JS与APP交互
这种情况一般是比较常见的,就是JS网页调用APP的方法做一些本地事情,然后是APP调用JS的方法反馈一些情况什么的。
而要实现这个最重要的一个设置就是这个 mWebSettings.setJavaScriptEnabled(true); 要使能webview可以调用JS方法
1)APP调用JS方法
mWebView.loadUrl("javascript:test()");// 调用js函数无参数
mWebView.loadUrl("javascript:test(test)"); //test是js的函数test()的参数
2)JS调用APP方法 JS调用APP的方法也比较简单,只要添加JavascriptInterface方法接口即可
mWebView.addJavascriptInterface(mWebAppInterface, "AndroidWebAppInterface");
然后实现JS需要调用的方法,这里需要注意的就是安卓版本大于17的时候,需要在JS方法上加上注解
@JavascriptInterface
@JavascriptInterface
@JavascriptInterface
重要的事情说三遍
// 如果target 大于等于API 17,则需要加上如下注解
@JavascriptInterface
public void showToast(String toast) {
LogUtils.d(TAG, "toast = " + toast);
Toast.makeText(mContext, toast, Toast.LENGTH_LONG).show();
}
三、HTML5数据存储(LocalStorage)
有时候网页需要自己保存一些关键数据,这个时候就需要用到像LocalStorage这些东西了,而安卓WebView默认是无法使用的,也是需要用户自己配置的,感觉好坑啊,IOS的直接加载啥都不用配置就都能用了,安卓直接用啥都不行,感觉被虐惨了。下面是关键配置,最最重要就是这个
mWebSettings.setDomStorageEnabled(true); mWebSettings.setDomStorageEnabled(true); mWebSettings.setDomStorageEnabled(true);
重要的事情说三遍
mWebSettings.setDomStorageEnabled(true);
mWebSettings.setDatabaseEnabled(true);
mWebSettings.setAppCacheEnabled(true);
String appCachePath = getApplicationContext().getCacheDir().getAbsolutePath();
mWebSettings.setAppCachePath(appCachePath);
四、HTML5定位(获取当前地址)
存储完了,就该是定位了,有时候网页想自己直接获取定位地址,就需要用到定位配置了。当然该有的权限还是得自己加上,比如:
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
主要的配置就是需要复写WebChromeClient的三个方法
@Override
public void onReceivedIcon(WebView view, Bitmap icon) {
super.onReceivedIcon(view, icon);
}
@Override
public void onGeolocationPermissionsHidePrompt() {
super.onGeolocationPermissionsHidePrompt();
}
@Override
public void onGeolocationPermissionsShowPrompt(final String origin, final GeolocationPermissions.Callback callback) {
callback.invoke(origin, true, false);//注意个函数,第二个参数就是是否同意定位权限,第三个是是否希望内核记住
super.onGeolocationPermissionsShowPrompt(origin, callback);
}
基本加上上面的配置基本就OK了,没啥大问题。
五、遇到的其它坑
1)多窗口的问题
html中的_bank标签就是新建窗口,在处理多窗口的时候需要配置下面的设置,不然可能点击没有反应
mWebSettings.setSupportMultipleWindows(true);
mWebSettings.setJavaScriptCanOpenWindowsAutomatically(true);
然后可以复写一下WebChromeClient的onCreateWindow方法
@Override
public boolean onCreateWindow(WebView view, boolean isDialog,
boolean isUserGesture, Message resultMsg) {
WebView.WebViewTransport transport = (WebView.WebViewTransport) resultMsg.obj;
transport.setWebView(mWebView);
resultMsg.sendToTarget();
return true;
}
2)多页面在同一个WebView中打开,就是不新建activity或者调用系统浏览器打开,需要复写WebViewClient的shouldOverrideUrlLoading方法.
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
3)WebView进行Http数据请求 这个相对也不复杂,主要是https坑比较大,加载数据基本用下面的就可以了
private void getWebData() {
new Thread() {
@Override
public void run() {
OkHttpClient okHttpClient = HttpClientSslHelper.getSslOkHttpClient(getApplicationContext(), AppApiContact.bServerDebug);//new OkHttpClient();
okHttpClient.setConnectTimeout(15, TimeUnit.SECONDS);
Request request = new Request.Builder()
.url(mWebUrl)
.build();
try {
Response response = okHttpClient.newCall(request).execute();
final String data = response.body().string();
LogUtils.d(TAG, "data = " + data);
runOnUiThread(new Runnable() {
@Override
public void run() {
if (StringHelper.notEmpty(data) && !isDestroy) {//页面销毁之后不做处理
// mWebView.loadData(data, "text/html; charset=UTF-8", null);
mWebView.loadDataWithBaseURL(null, data, "text/html", "UTF-8", null);
}
}
});
} catch (IOException e) {
e.printStackTrace();
}
}
}.start();
}
4)WebView进行HTTPS加密加载(这个坑貌似我还没解决,用的上面的第三种方法绕过去了)
5)JS调用安卓接口传输JSON格式数据 这个真是个大坑,以前一直没啥问题,直接传字符串数据结构就过来了,安卓也能直接解析,但是最近遇到安卓这边接受到数据死活不对,总是undefined值,也就是传输出问题了,后来反复排查才发现,需要对JSON数据字符串进行转义传输,不然就解析不到,也是无语了,例子如下
"
{
"title":"test title"
}
"
以前传这种字符串过来是可以正常解析的,也不知道发什么神经,突然不行了,必须做转义之后传这种才可以解析
"
{
\"title\":\"test title\"
}
"
目前好像就遇到这些,等再遇到了再来更新吧,下面给出全部的配置
private void setUpViewComponent() {
WebSettings mWebSettings = mWebView.getSettings();
mWebSettings.setSupportZoom(true);
mWebSettings.setLoadWithOverviewMode(true);
mWebSettings.setUseWideViewPort(true);
mWebSettings.setJavaScriptEnabled(true);
mWebSettings.setDefaultTextEncodingName("GBK");
mWebSettings.setSupportMultipleWindows(true);
mWebSettings.setLoadsImagesAutomatically(true);
mWebSettings.setDomStorageEnabled(true);
mWebSettings.setDatabaseEnabled(true);
mWebSettings.setAppCacheEnabled(true);
String appCachePath = getApplicationContext().getCacheDir().getAbsolutePath();
mWebSettings.setAppCachePath(appCachePath);
mWebSettings.setAllowFileAccess(true);
if (AppApplication.getSdkVersion() >= 11) {
mWebSettings.setDisplayZoomControls(false);
} else {
setZoomControlGone(mWebView); //Android 3.0(11) 以下使用以下方法
}
mSwipeContainer.setOnRefreshListener(this);
mWebAppInterface = new WebAppInterface(this);
setWebViewListener();
}
private void setZoomControlGone(View view) {
Class classType;
Field field;
try {
classType = WebView.class;
field = classType.getDeclaredField("mZoomButtonsController");
field.setAccessible(true);
ZoomButtonsController mZoomButtonsController = new ZoomButtonsController(
view);
mZoomButtonsController.getZoomControls().setVisibility(View.GONE);
try {
field.set(view, mZoomButtonsController);
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
} catch (SecurityException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (Exception ee) {
ee.printStackTrace();
}
}
private void setWebViewListener() {
mWebView.addJavascriptInterface(mWebAppInterface, "AndroidWebAppInterface");
WebViewClient webClient = new CustWebViewClient();
mWebView.setWebViewClient(webClient);
mWebView.setWebChromeClient(new WebChromeClient() {
@Override
public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
return super.onJsAlert(view, url, message, result);
}
@Override
public boolean onCreateWindow(WebView view, boolean isDialog, boolean isUserGesture, Message resultMsg) {
return super.onCreateWindow(view, isDialog, isUserGesture, resultMsg);
}
});
mWebView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View arg0) {
return true;
}
});
}
private class CustomWebViewClient extends WebViewClient {
public CustomWebViewClient() {
super();
}
public boolean shouldOverrideUrlLoading(WebView view, String url) { // 重写此方法表明点击网页里面的链接还是在当前的Web view里跳转,不跳到浏览器那边
LogUtils.d(TAG, "url --" + url);
view.loadUrl(url);
return true;
}
@Override
public void onLoadResource(WebView view, String url) {
}
@Override
public void onPageFinished(WebView view, String url) {
mSwipeContainer.setRefreshing(false);
}
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
mSwipeContainer.setRefreshing(true);
}
}
private void getWebData() {
new Thread() {
@Override
public void run() {
OkHttpClient okHttpClient = HttpClientSslHelper.getSslOkHttpClient(getApplicationContext(), AppApiContact.bServerDebug);//new OkHttpClient();
okHttpClient.setConnectTimeout(15, TimeUnit.SECONDS);
Request request = new Request.Builder()
.url(mWebUrl)
.build();
try {
Response response = okHttpClient.newCall(request).execute();
final String data = response.body().string();
LogUtils.d(TAG, "data = " + data);
runOnUiThread(new Runnable() {
@Override
public void run() {
if (StringHelper.notEmpty(data) && !isDestroy) {//页面销毁之后不做处理
// mWebView.loadData(data, "text/html; charset=UTF-8", null);
mWebView.loadDataWithBaseURL(null, data, "text/html", "UTF-8", null);
}
}
});
} catch (IOException e) {
e.printStackTrace();
}
}
}.start();
Recommend
-
272
webview A tiny cross-platform webview library for C/C++/Go to build modern cross-platform GUIs. The goal of the project is to create a common HTML5 UI abstraction layer for the most widely used platforms. It supports two-way...
-
87
前言:随着市场需求的不断变化,原生安卓已经无法满足客户的需要了,现在很多app都在使用Android和h5的交互实现某些功能,比如商品详情页,文章详情页面,商品点评页面,还有某些复杂的展示页面等等,设置登陆页面都有可能是和js交互做到的。通过交互可以很快速的...
-
4
[本文结构] 由于工作的原因,现在开始接触一些iOS相关的开发工作,因此就逐渐汇总整理一些开发过程中的基础问题吧。这篇主要介绍首次使用Xcode过程中一些配置相关的内容
-
9
最近忙着写代码和倒腾AS,好久没写博客了,今天就小小总结一下个人使用AS中遇到的不太顺手的点,备忘一下。 电脑上的Android Studio装了已经有些时间了,然而因为所有工作中的项目都是ADT,所以虽然垂涎已久,但都是浅尝辄止。最近发现个开源项目挺好,...
-
20
1、打开手机便签后点击底部“我的”按钮,接着点击提醒设置。 2、在提醒设置页面,我们点击预设提醒日期配置。 3、接着在预设提醒日期配置页面中可以看到默认的5个预设提醒日期,我们可以点击“+”按钮新增自定义的提醒设置。 4、在弹窗中可以...
-
24
...
-
5
...
-
7
MrLeiDeSen's Blog 安卓WebView同Javascript通信2021-03-26 08:41:01 · MrLeiDeSen前言#...
-
8
ChatGPT 主题相关的安卓恶意软件开始涌现 作者:FreeBuf.COM 2023-06-29 12:48:22 安全 随着 OpenAI 研发的 GPT 3.5 与 GPT 4.0 的...
-
5
网易有爱插件有很多的用户在玩游戏的时候选择了这款软件,不过没有经验操作时遇到不少问题的小伙伴不在少数,下面就带来了网易有爱插件设置使用问题汇总,可以让你们更好的去进行解决。 网易有爱插件怎么安装: 1、首先需要网易有爱插件,用...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK