❶ WebView返回时停留在第一层界面,重复刷新此界面
WebView详细解析:
https://www.jianshu.com/p/b8526e6b7760
解决方法:
boolean canGoBack():用来确认WebView里是否还有可回退的历史记录。通常我们会在WebView里重写返回键的点击事件,通过该方法判断WebView里是否还有历史记录,若有则返回上一页。
@Override
override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
if (interesWeb.canGoBack()) {
interesWeb.goBack();
return true;
}else {
finish();
}
return super.onKeyDown(keyCode, event);
}
此方法可以实现逐级返回上层webview界面,但是如果WebView的第一个界面只有在首次进入时显示的话,就会造成后续返回时,一直停留在当前界面无法退出这个Activity界面(我的使用场景如此)
onKeyDown方法还会造成一个问题,就是在webview界面的时候,如果当前这个界面需要播放音频,你通过音量键调节音量的时候,会导致界面后退。
替换方案:
override fun onBackPressed() {
if (interesWeb.canGoBackOrForward(-2)) {
interesWeb.goBack();
}else {
finish();
}
}
可以通过onBackPressed()来替代onKeyDown方法。canGoBackOrForward()替换canGoBack()方法。
boolean canGoBackOrForward(int steps):以当前的页面为起始点,用来确认WebView的历史记录是否足以后退或前进给定的步数,扒轮毕正数为前进,负数为后退。(详细解释可以看上面的链接: https://www.jianshu.com/p/b8526e6b7760 )
同时,在使用原生的webView进行页面加载时,需要注意相春芹关属性的桐察配置。
参考:
1、 android WebView 详解
2、 WebView·开车指南
3、 Android WebView 常用API参考手册
❷ 安卓WebView详解 (三)--Webview的API及说明
android.view.ViewGroup
↳ android.widget.AbsoluteLayout
↳android.webkit.WebView
用于安卓显示网页内容
一、查找网页中匹配的字符串
1、void findAllAsync ( String find) 查滚悄找网页乱搭中匹配的字符串且高亮显示,此方法为异步方法,对应的结果会在 WebView.FindListener中回调
2、void findNext (boolean forward) 上下查找匹配字符串
3、void addjavascriptInterface ( Object object, String name) 将提供的Java对象注入到此WebView中
4、void autofill( SparseArray < AutofillValue > values) 自动填充该视图中虚拟子级的内容
5、boolean canGoBack () 获取此WebView是否具有后退历史记录项。
6、boolean canGoBackOrForward (int steps) 获取页面是大陪渣否可以前进或后退给定数量的步骤。
7、boolean canGoForward () 获取此WebView是否具有转发历史记录项。
8、void clearCache (boolean includeDiskFiles) 清除缓存
9、void clearClientCertPreferences ( Runnable onCleared) 清除响应于继续/取消客户端证书请求而存储的客户端证书首选项。
10、void clearFormData() 从当前关注的表单字段中删除自动完成弹出窗口(如果存在)。
11、void clearHistory () 告诉此WebView清除其内部后退/前进列表
❸ Android WebView 调用系统拍照和相册
由于业务需要,APP内嵌H5,需要调去系统相册和拍照,网上找了点资料,整理一下,供大家参考:
private static final int REQUEST_CAMERA =1;
private static final int REQUEST_CHOOSE =2;
private ValueCallbackmUploadMessage;
private ;
private UricameraUri;
//5.0以后的方法
webView.setWebChromeClient(new WebChromeClient() {
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
public boolean onShowFileChooser(WebView webView, ValueCallback filePathCallback, FileChooserParams fileChooserParams) {
if (mUploadMessagesAboveL !=null) {
mUploadMessagesAboveL.onReceiveValue(null);
mUploadMessagesAboveL =null;
}else {
mUploadMessagesAboveL = filePathCallback;
selectImage();
}
return true;
}
});
//选择图片和拍照,对应的string文件,可以自己写死:拍照,相册,取消
private void selectImage() {
ActionSheet.createBuilder(this, getSupportFragmentManager()).
setOtherButtonTitles(new String[]{getResources().getString(R.string.common_tip_photos), getResources().getString(R.string.common_picture)}).
setCancelButtonTitle(getResources().getString(R.string.common_cancel)).setCancelableOnTouchOutside(true).setListener(new ActionSheet.ActionSheetListener() {
public void onDismiss(ActionSheet actionSheet, boolean isCancel) {
if (mUploadMessage !=null) {
mUploadMessage.onReceiveValue(null);
mUploadMessage =null;
}
if (mUploadMessagesAboveL !=null) {
mUploadMessagesAboveL.onReceiveValue(null);
mUploadMessagesAboveL =null;
}
actionSheet.dismiss();
}
@RequiresApi(api = Build.VERSION_CODES.M)
public void onOtherButtonClick(ActionSheet actionSheet, int index) {
switch (index) {
case 0:
chosePicture();
break;
case 1:
setRequestCamera();
}
}
}).show();
}
//拍照,添加权限申请 这个可以自己写下,我这边是项目中写好的,直接拿过来用了
public void setRequestCamera() {
permissionsBuilder =new YXTPermissionsBuilder.Builder(this)
.setOnGrantedListener((requestCode, perms) -> {
openCamera();
})
.setRationale4NeverAskAgain(LanguageUtils.isEnglish() ? String.format(getString(R.string.permission_tips), getString(R.string.common_camera), getString(R.string.app_name), getString(R.string.app_name)) :
String.format(getString(R.string.permission_tips), getString(R.string.app_name), getString(R.string.common_camera), getString(R.string.app_name)))
//必需
.setRequestCode(ConstantsData.GET_CAMERA)
.build();
permissionsBuilder.requestPermissions(Manifest.permission.CAMERA);
}
/**
* 本地相册选择图片
*/
private void chosePicture() {
Intent innerIntent =new Intent(Intent.ACTION_GET_CONTENT, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
innerIntent.setType("image/*");
Intent wrapperIntent = Intent.createChooser(innerIntent, null);
startActivityForResult(wrapperIntent, REQUEST_CHOOSE);
}
/**
* 打开照相机
*/
private void openCamera() {
Intent intent =new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
String imagePaths = Environment.getExternalStorageDirectory().getPath() +"/pbccrc/Images/" + (System.currentTimeMillis() +".jpg");
// 必须确保文件夹路径存在,否则拍照后无法完成回调
File vFile =new File(imagePaths);
if (!vFile.exists()) {
File vDirPath = vFile.getParentFile();
vDirPath.mkdirs();
}else {
if (vFile.exists()) {
vFile.delete();
}
}
cameraUri = FileProvider.getUriForFile(
this,
getPackageName() +".fileprovider",
vFile);
intent.putExtra(MediaStore.EXTRA_OUTPUT, cameraUri);
startActivityForResult(intent, REQUEST_CAMERA);
}
/**
* 选择照片后结束
*
* @param data
*/
private UriafterChosePic(Intent data) {
if (data !=null) {
final String path = data.getData().getPath();
if (path !=null && (path.endsWith(".png") || path.endsWith(".PNG") || path.endsWith(".jpg") || path.endsWith(".JPG"))) {
return data.getData();
}else {
Toast.makeText(this, "上传的图片仅支持png或jpg格式", Toast.LENGTH_SHORT).show();
}
}
return null;
}
/**
* 返回文件选择
*/
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
if (mUploadMessagesAboveL !=null) {
onActivityResultAboveL(requestCode, resultCode, intent);
}
if (mUploadMessage ==null)return;
Uri uri =null;
if (requestCode ==REQUEST_CAMERA && resultCode ==RESULT_OK) {
uri =cameraUri;
Log.e("onActivityResult: " + uri.toString());
}
if (requestCode ==REQUEST_CHOOSE && resultCode ==RESULT_OK) {
uri = afterChosePic(intent);
}
mUploadMessage.onReceiveValue(uri);
mUploadMessage =null;
super.onActivityResult(requestCode, resultCode, intent);
}
/**
* 5.0以后机型 返回文件选择
*
* @param requestCode
* @param resultCode
* @param data
*/
private void onActivityResultAboveL(int requestCode, int resultCode, Intent data) {
Uri[] results =null;
if (requestCode ==REQUEST_CAMERA && resultCode ==RESULT_OK) {
results =new Uri[]{cameraUri};
}
if (requestCode ==REQUEST_CHOOSE && resultCode ==RESULT_OK) {
if (data !=null) {
String dataString = data.getDataString();
if (dataString !=null)
results =new Uri[]{Uri.parse(dataString)};
}
}
mUploadMessagesAboveL.onReceiveValue(results);
mUploadMessagesAboveL =null;
return;
}
基本都可以拿去用了,希望有帮助
❹ 安卓7.0中多线程web view开启有什么用
WebView是一个基于webkit引擎、展现web页面的控件。
作用:
1、显示和渲染Web页面,直接使用html文件(网络上或本地assets中)作布局,可和JavaScript交互调用。
2、WebView控件功能强大,除了具有一般View的属性和设置外,还可以对url请求、页面加载、渲染、页面交互进行强大的处理。
❺ Android系统 WebView是什么有什么用
现在越来越多的APP都内置了Web网页去加载视图,也就是我们常说的Hybrid APP混合应用,市场上很多平台都是这样做的,比如我们经常使用的淘宝、京东等电商平台。这些是如何实现的呢?在我们Android中有一个WebView组件,它就可以实现此类功能。它是Android中的原生UI控件,主要用于在APP应用中方便地访问远程网页或本地HTML资源,同时WebView也在Android中充当Java代码和JS代码之间交互的桥梁,实际上也可以将WebView看做一个功能最小化的浏览器。下面我们一起来看看WebView的一些常用的使用方法。
WebView是Android系统提供的一个能显示网页的系统控件,它是一个特殊的View,同时也是一个ViewGroup,可以有很多其他子View。在Android 4.4以下(不包含4.4)系统WebView底层实现是采用WebKit内核,而在Android 4.4及其以上Google采用了Chromium内核作为系统WebView的底层内核支持。在这一变化中Android提供的WebView相关API并没有发生较大变化,在4.4上也兼容低版本的API并且引进了少部分API。这里简单介绍下基于Chromium的WebView和基于WebKit的WebView之间的差异,基于Chromium的Webview提供了更广的HTML5、CSS3、JavaScript支持,在Android系统版本5.0上基于Chromium 37,WebView提供了绝大多数的HTML5特性支持,除此之外Chromium也支持远程调试(Chrome DevTools)。WebKit JavaScript引起采用WebCore JavaScript在Android 4.4上换成了V8能直接提升JavaScript性能。
二、作用
1、显示和渲染Web页面
2、使用html文件(网络上或本地assets中)作为布局
3、可与JavaScript交互调用
注: WebView控件功能强大,除了具有一般View的属性和设置外,还可以对Url请求、页面加载、渲染、页面交互进行强大的处理。
❻ app中的webview是什么如何理解
当你上网阅读东西时,我们一般会选择一款浏览器,比如Chrome、火狐、safari、IE或者Edge。你可能不知道这些浏览器之间有一些竞争,而竞争的主要形式就是WebView。
WebView的定义
什么是WebView呢?它是本地应用程序内嵌的一个浏览器!这句话有两处需要搞清楚!
上面是火狐的一个页面,红色区域可以认为是WebView,它拥有渲染引擎,可以通过http/https请求加载内容,加载回来的代码就可以被执行和渲染出来。红色区域以上的部分就是浏览器本地的UI组件。
移动端app中WebView的特点
我们经常把h5页面内嵌入app中喊御,这种就是混合型的app,除了渲染页面本身的功能外,页面中的js还有能力调用app系统接口的,比如某些弹窗、分享等,这些区别对用户来说都是无感知的。
在普通浏览器中是没有这个能力的,至少浏览器没有开放这些api。
WebView中的渲染引擎 WebView带来的好处 总结
可以认为WebView就是浏览器,只是在不同平台长相和能力有所不同!
App中的WebView可以理解为一个浏览器,因为它具有基本的浏览器能力,包括加载网页,js控制等;
首先,看一下安卓端webview的一些介绍。
是一个基于引擎、展现页面的控件。可以显示和渲染Web页面,与JS交互,也可以和原生代码交互。
然后可以参考下各大APP,如淘宝、支付宝、京东、美团等;这里截取几张图示例下。
(截图来自支付宝、淘宝),上面2个页面都是在app内内嵌了定制坦渗棚的webview组件,用于展示一些额外的信息(非组件化的),灵活性高;
其次,webview作为app中重要的组成部分,如混合APP, 纯H5 App;
最后,题主若还有疑问,欢迎@我。
WebView(网络视图)能加载显示网页,可以将其视为一个浏览器。
在Android手机中,网页的解析和显示网页的能力是由webkit内核实现的。
(如chrome浏览器使用的是webkit内核,现在,webkit被内置到了android系统中)
webview对网页处理也是交给强大的webkit做的
webview在android SDK(原生)中:
封装为一个叫做WebView组件,通过这个组件可以在app中显示html+css+js,当然也就可以显示一个远程url,比如用它打开网络首页是可以的。
可以理解为:android开发中的一个activity里使用了webview组件,并打开了一个html页面呈现给用户。
其中“activity”是android原生开发时的“一张页面”,app的所谓跳转到不同“页”是在activity中跳来跳去,activity是java的一个类,布局则是使用xml(如果没做过原生android开发就这么理解就行)
webview在mui app框架开发中:
在mui开发中,这些webview就是一张一张的网页。
这些网页是webview对象,其操作方法被封让则装在html5+的plus.webview对象中
webview本身只是个浏览器效果组件,切换即使网页之间的跳转,理论上不可能像原生的activity中切换一样流畅,本身也不会有什么动画。
还好,mui的开发组,dcloud(数字天堂)和他们的html5+中国产业联盟(社区)实现了webview切换的动画效果,他们把这些webview映射到了真正的java webview,调用的也是原生的activity切换动画,从而使得webview切换也可以像原生app activity一样切换的效果!图一(简约图)原生开发和mui的hybrid模式区别图:(图二)希望帮助到你![玫瑰]
❼ Android WebView 在开发过程中有哪些坑
WebViewClient.onPageFinished()。你永远无法确定当WebView调用这个方法的时候,网页内容是否真的加载完毕了。当前正在加载的网页产生跳转的时候这个方法禅亏可能会被多次调用,StackOverflow上有比较具体的解释(How to listen for a Webview finishing loading a URL in Android?), 但其中列举的解决方法并不完美。所以当你的WebView需要加载各种各样的网页并且需要在页面加载完成时采取一些操作的话,可能WebChromeClient.onProgressChanged()比WebViewClient.onPageFinished()都要靠谱一些。
WebView后台耗电问题。当你的程序调用了WebView加载网页,WebView会自己开启一些线程(?),如果你没有正确地将WebView销毁帆袭耐的话,这些残余的线程(?)会一直在后台运行,由此导致你的应用程序耗电量居高不下。对此我采用的处理方式比较偷懒,简单又粗暴(不建议),即在Activity.onDestroy()中直接调用System.exit(0),使得应用程序完全被移出虚拟机,这样就不会有任何问题了。
切换WebView闪屏问题。如果你需要在同一个ViewGroup中来回切换不同的WebView(包含了不同的网页内容)的话,你就会发现闪屏是不可避免的。这态春应该是Android硬件加速的Bug,如果关闭硬件加速这种情况会好很多,但无法获得很好的浏览体验,你会感觉网页滑动的时候一卡一卡的,不跟手。
数据积累问题。开启缓存什么的有利于网页的浏览体验,但你会发现即使是清除了必要的内容,比如Cache、Cookie、Form Data、History、Password等等东西,你的应用程序所占用的存储空间还是会越来越大,到最后只好手动到系统设置的应用信息界面里清除数据了 :(
滚动条问题。Android System WebView的横向滚动条真是好粗的有木有
❽ 关于Android WebView的那些事
[TOC]
Webkit是一个开源浏览器项目,其中,对Android开发者来说,或多或少的都有些接触。 在应用层来看,最经常使用无非这么几个类:WebView(Android中最为复杂,也是最为简单的一个View,继承自AbsoluteLayout),WebViewClient、WebChromeClient(作为回调控制类)、WebSettings(进行设置项的配置)等;Webkit内部包含了网络请求、页面渲染、Js引擎等等。在Android4.4之前的版本中,系统使用的是Webkit内核,其后,切换到Google的Chromium内核。本文主要介绍的是在Android中,如何使用Webkit进行H5页面的展现,以及常见问题的分析手段。
下面的内容抄自网络 & 乱七八糟的地方,简单了解一下。
<b><i>前面都是吹牛逼的信息,如何使用Webkit来更好的搬砖? 且听如下分解</i></b>
XML布局中丢一个 <WebView> 标签,然后再 Activity 或者 Fragment 中 findViewById ,进而 loadUrl ,一般也没人这么简单的用,除非写Demo。很简单,它就是一个Layout,提供了一个调用加载页面的接口,不写范例了,能看到这篇文章的都看过Google的API说明。
主要涉及到WebView和WebSettings两个类。
例如:
其实就是WebView的父类ViewGroup和View的方法,不多说了。不过需要注意的是,不是所有的View或ViewGroup的方法对WebView都生效。
列举几类常用的,几乎所有App的 WebView 都会设置的属性:
</br>
如何处理页面跳转以及特殊 Scheme
这个回调可以说是最容易出问题的一个回调,表示什么? 字面意思,让你重写这个URL 的loading,比如点击html打电话的一个 <a href=“tel:110”> 标签,作为一个有节操、有责任心的浏览器,你需要处理 H5常用的几个Scheme :
除此之外,还有各个应用自定义的scheme ,举个例子,支付宝的支付Scheme : alipay: 。 这里的返回值,就代表你有没有能力处理这个url,没有的话Webkit就默认处理了。
需要注意的是,这个回调的触发的绝大多数情况是点击页面的 <a href="xxxx"> a标签,在Android中 loadUrl("http://www..com") ,是不会回调的,为什么不会回调,各位自行理解吧。
超链接 <a> 标签怎么写: 点我
特别说下窗口常见的两种打开方式:
针对单页模式的WebView框架(所有的html窗口均使用同一个WebView实例),不需要关注target的。
如果作为一个成熟的浏览器框架的话,是需要支持Html、JavaScript使用新窗口打开页面,需要实现如下回调:
还有一个相关设置项: WebSettings.
此时,系统将不会再回调 shouldOverrideUrlLoading 。新窗口逻辑的具体实现机制,可以参考系统browser实现逻辑。
<b> 这里有个坑 </b>
Android 4.4版本 ,如果实现了onCreateWindow,也就是说页面 <a> 标签是这么写的: <a href="http://www..com" target="_blank"> ,点击此链接打开的新WebView窗口,此窗口中的url点击,是不会触发 shouldOverrideUrlLoading 。 这是刚替换成Chrominum内核出的一个bug。本人并没在新版本上验证是否已经修复。
另外,根据不同的Rom,底层实现是不一样的,有的ROM会帮你处理各种调起scheme,也就是startActivity,有的ROM点一个url,就会抛一个intent出来,让用户选择系统浏览器进行加载。
系统默认,提供了一个接口:
有什么安全隐患呢?
戳这里
如果不知道Js怎么写, 请戳我
用PC的截图意思一下,看出区别了吧。 这里确定、取消点击以后就得调用 JsResult、JsPromptResult 的 confirm或者cancel。
因为安全问题,大一些的App Native与Js通信都不再用 WebView.addJavascriptInterface(Object) 了,都改用JsPrompt,因为JsPrompt中有message、有JsPromptResult可以返回给Js一些信息,所以桥选中了JsPrompt,另一个备选方案是JsConsole。
大体有这么几种方式进行传递
具体方案实现时,多方面考虑使用何种方式。
还有一个比较牛逼的
系统源码中均有方法注释,怎么用自己看吧。
那么问题来了
查了下,只有这两个相关的:
WebBackForwardList BackForwardList()
void clearHistory()
系统提供的关于历史记录的操作并不多,因为,不支持单条删除啊,啊啊啊!
WebViewClient中,还有一个相关callback,当系统更新历史记录时回调:
void doUpdateVisitedHistory(WebView view, String url, boolean isReload)
<b>相关问题分析法:历史栈回退错误的定位</b>
绝大多数回退错误是由于接口调用、回调中逻辑执行时序错误。
定位方法:利用 BackForwardList , doUpdateVisitedHistory 两个接口在 loadUrl、onPageStart、onPageFinish 以及逻辑相关的地方调用,打log,查看历史栈,这里注意下由于loarl是异步的,需要考虑是否加延迟等等保证调用时机的准确。
本人曾经遇到一个问题:在WebChromeClient中的 JsPrompt回调中,直接进行WebView.goBack操作,结果发现WebView确实回退到上一个页面,但是BackFowardList当前页面的index未更新的问题,具体见另一个篇blog。
网上有很多关于WebView内存泄露的讨论,据传,老版本的WebView在展示大量图片的时候,即使 WebView.destory() WebView=null ,也不会销毁。
在新版本上,实际测试结果:compileSDKVersion 23 不会泄露。
一般,我们如何销毁WebView比较保险?
这个问题好大。。。
暂时不介绍,另起blog进行说明。
解决方案:
实现回调 void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error)
首先,提几个需要注意的点:
个人归纳总结几点:
step1 进入开发者模式,勾选“显示布局边界”;
step 2,回到你想查看的界面; step 3 假如内容区只有一层基本就是H5 WebView的,多个层级,就是Native。
看到左右图的差异了吧。
还有另一种方法,RD屌丝们看这里,特别说明,这种方法不太适合浏览器。 (自有内核,可能会不准确)
好了,就介绍到这里,零零散散的几年前写的文章,第一篇blog,如有不对的地方,还恳请大家指正。
❾ android开发中,webview常用于显示网页或h5页面,一个遇到跨域方面的坑。
1.跨域cookie读取
什么是跨域,简单的说就是不同的域名,我们都知道在pc上我们用浏览器访问网址,不同的网址都会在本地存储一些cookie信息,这样就可以实现比如自扒核棚动登录等功能,在pc上不同域名是不能相互读取其他域下的cookie信息的(非web专业开发人员,如果理解有误,欢迎指出)。
但是在 android 上在api 23之前,是可以跨域读取cookie的,比如A域写入一个userId的cookie,B域可以读取该值。但是在23时,系统将该值设置成了false,不再让跨域读取了。如果你的应用有跨域读取需求,怎么办?可以采用如下方式进行开启:
/*** 设置跨域cookie读取*/
public final void setAcceptThirdPartyCookies() {
//target 23 default false, so manual set true
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { CookieManager.getInstance().setAcceptThirdPartyCookies(webView,true);
}
}
2.http/https混合加载
在现阶段,很多网站都改成了https进行访问,https可以提升访问网站的安全性,防止信息被窃取,如果所有的网页都是https且网页内的链接也是都是https,那就没春则有混合加载(文本区域https,图片文件http加载)的问题了。但是很多资源现阶段还没有改变成https访问,往往页面都嵌入了http的链接。这种混合网页如果不进行处理,直接加载是会出现错误的。怎么解决这个问题?
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
webSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
}
这也是一个分版本氏缺的函数,在api23之前,默认是可以混合加载的,但是在23时,默认值改成了MIXED_CONTENT_NEVER_ALLOW,因此如果你有混合加载的需求,设置setMixedContentMode为MIXED_CONTENT_ALWAYS_ALLOW。
3.无法解决跨域访问问题,可以尝试给webview设置如下配置,已解决该问题;
if (Build.VERSION.SDK_INT >= 16) {
Class clazz =webView.getSettings().getClass();
Method method = clazz.getMethod("", boolean.class);
if (method != null) {
method.invoke(webView.getSettings(), true);
}
}
} catch (IllegalArgumentExceptione) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
❿ Android WebView 在开发过程中有哪些坑
WebView功能强大,应用广泛,一方面它增强了APP的上网体验,让APP功能更多样化,另一方面它也引入了很多的安全问题。
已知的WebView任意代码执行漏洞有4个。
Java代码和网页中的JavaScript脚本扮猜交互,在WebView控件中实现了addJavascriptInterface接口。
网页中的js脚本可以利用接口“myjs”调用App中的Java代码,而Java对象继承关系会导致很多Public的函数及getClass函数都可以在JS中被访问,结合Java的反射机岁兄制,攻击者还可以获得系统类的函数,进而厅雀型可以进行任意代码执行。