webview是一个内置的系统组件,能够显著提升手机的流畅度,增强用户体验。只需访问一个网页,该组件便会自动进行更新,它支持完全的JavaScript执行环境,并允许本地代码进行双向通信。该软件定期发布安全补丁,同时具备GPU加速绘图功能,从而形成更为综合的用户体验。每次使用的历史记录都会被保留,以满足用户的多样化需求。
webview怎么用?
需求1:根据URL加载网页
1、直接在Activity中加载一个WebView。
运行效果图:
2、在布局代码中设置WebView。
相信大家都遇到过许多新闻类或者门户类的应用,其整体结构大概如下:
左上角通常会有一个可用来关闭当前Activity的按钮,中间为新闻标题,右侧配有一个刷新按钮,而在右下角还可能有一个悬浮按钮,当我们向右滑动超过屏幕边界时,它会自动显现。当用户点击该按钮时,页面将回滚至顶部。接下来,我们一同实现这个功能!
运行效果图:
WebView的几个常见功能使用方法
android的WebView组件功能强大,本项目中常用的几个功能总结如下:
一、背景设置
WebView.setBackgroundColor(0); // 先将背景色设为透明
WebView.setBackgroundResource(R.drawable.yourImage); // 然后设置背景图片
二、获得WebView网页加载初始化和完成事件
步骤:
1、创建一个自定义的WebViewClient类(继承自WebViewClient)例如创建WebViewClient。
2、重载onPageFinished(WebView view, String url)方法(当webview加载完成时会调用此方法),在此方法中放入加载完成后的操作。
3、通过webView.setWebViewClient(new WebViewClient());关联自定义的webviewclient与webview。
如需监控加载进度,还需创建一个自定义的WebChromeClient类,并重载onProgressChanged方法,然后继续进行设置。
布局文件:
注意,涉及到webView的一系列用法,比如webView.getSettings().setJavaScriptEnabled(true);此方法用于启用JavaScript。
等具体实现,请参阅API文档。
使用进度条时,在实例化setWebChromeClient之后,可以在内部类中实现onProgressChanged事件。
WebView中,某些任务不必由WebView类处理,部分工作可以由其它类分担,这样WebView可以专注于解析和渲染功能。
WebViewClient的职责是帮助WebView处理各种通知和请求事件,具体包括:
onLoadResource
onPageStart
onPageFinish
onReceiveError
onReceivedHttpAuthRequest
WebChromeClient则辅助WebView处理Javascript对话框、网站图标、网站标题和页面加载进度等,包括:
onCloseWindow(关闭WebView)
onCreateWindow()
onJsAlert(弹出alert提示框需定制WebChromeClient)
onJsPrompt
onJsConfirm
onProgressChanged
onReceivedIcon
onReceivedTitle
以上内容希望对各位学习有所帮助,也感谢大家对3322的支持。
Android WebView的具体实现与Chromium渲染引擎启动过程
以Android 8.0源码为例,首先找到WebView的真正构造函数:
该构造函数会调用另一个成员函数ensureProviderCreated()以确保Chromium动态库已被加载。在Chromium动态库加载成功后,WebView类的成员函数ensureProviderCreated也会创建一个WebViewProvider对象,并将其保存于成员变量mProvider中。这个WebViewProvider才是真正实现WebView功能的关键组件。上述Android WebView的主要操作基本都是通过mProvider来实现,比如loadUrl(String url)等功能。
有了mProvider后,WebView类的构造函数会继续调用mProvider.init(javaScriptInterfaces, privatepowsing)来启动网页渲染引擎。对于基于Chromium的WebView而言,使用的WebViewProvider对象是WebViewChromium。当调用WebViewChromium成员函数init时,它会启动Chromium网页渲染引擎。
按照我们的分析,接下来看看ensureProviderCreated的实现:
WebView类的epth已经是通过执行成员函数checkThread来保证它在WebView创建线程中执行,接下来需要判断成员变量mProvider的值是否为null。如果为null,则表示当前WebView尚未创建Provider。在这种情况下,会首先调用成员函数getFactory来获取WebViewFactory。在得到WebViewFactory后,可以利用其成员函数createWebView创建WebViewProvider。
接下来查看getFactory()方法及其实现:
getFactory返回的WebViewFactory是通过调用WebViewFactory类的静态成员函数getProvider获得的,getProvider首先判断静态成员变量sProviderInstance是否为null。如果为null,说明当前应用进程未加载过Chromium动态库。在这种情况下,需要加载Chromium动态库,同时创建WebViewFactory,并将其保存在静态成员变量sProviderInstance中。接着分析Chromium动态库的加载过程,再来看WebViewFactory的创建过程。
加载Chromium动态库是通过WebViewFactory类的静态成员函数loadNativeLibrary实现的:
loadNativeLibrary首先会通过成员函数getWebViewNativeLibraryPaths获取待加载的Chromium动态库路径,然后调用另一个静态成员函数nativeLoadWithRelroFile进行加载。加载时还会指定一个Chromium GNURELRO Section文件,该文件是在系统启动时通过启动一个临时进程生成的。nativeLoadWithRelroFile是一个JNI方法,由C++层的LoadWithRelroFile实现:
LoadWithRelroFile会判断当前是32位体系结构还是64位,然后从lib32和lib64参数中选择相应的Chromium动态库进行加载。
加载过程通过调用DoLoadWithRelroFile函数实现:
DoLoadWithRelroFile函数通过Linker导出的androiddlopenext函数,在Zygote进程保留的地址空间内加载Chromium动态库。注意,App进程是通过fork自Zygote进程,因此它同样拥有Zygote进程保留的地址空间。不过,DoLoadWithRelroFile会使androiddlopenext在加载时,将relro指定的GNURELRO Section文件内存映射,这样即可替代已加载Chromium动态库的GNURELRO Section。这通过传递ANDROIDDLEXTUSERELRO标志完成。此设计是因为relro描述的Chromium GNURELRO Section文件的加载地址与当前App进程中加载的Chromium动态库地址保持一致,只要两个相同的动态库在不同进程中加载地址一致,它们的链接与重定位信息即完全相符,因此可通过内存映射的共享方式来实现,从而节省内存空间。
此步骤完成后,App进程成功加载Chromium动态库。回到之前分析的WebViewFactory类静态成员函数getProvider,接下来会创建一个WebViewFactory,用于创建WebViewProvider。
WebViewFactory类的静态成员函数getProvider进行WebView Factory类型的确定,类型是通过静态成员函数getFactoryClass获得的:
由此可知,WebViewFactory类的静态成员函数getFactoryClass返回的WebView Factory类型为com.android.webview.chromium.WebViewChromiumFactoryProviderForO。这个类由WebView Package提供,意味着通过WebViewFactory类静态成员函数getProvider创建的WebView Factory为WebViewChromiumFactoryProvider对象:
WebViewChromiumFactoryProvider类构造函数会调用AwpowserProcess类的静态成员函数loadLibrary对之前加载的Chromium动态库进行初始化:
AwpowserProcess类的loadLibrary调用LiparyLoader类的静态成员函数loadNow实现Chromium动态库的初始化:
而LiparyLoader类的loadNow又会调用另一个重载的loadNow实现对Chromium动态库的初始化:
LiparyLoader类重载的loadNow又会调用loadAlreadyLocked静态成员函数对前面加载的Chromium动态库进行初始化:
并非所有系统都支持以文件内存映射的方式加载动态库,因此Chromium提供了一个Linker,能在动态库加载时实现文件内存映射以替换GNURELRO Section。针对Android 5.0以上版本,系统已提供此功能,因此Chromium不再使用自家的Linker,而是调用Android系统的Linker进行加载。调用System类的静态成员函数loadLibrary即可使用系统提供的Linker。
当LiparyLoader类的loadAlreadyLocked加载动态库时,通过NativeLiparies类的静态成员变量LIpARIES指定待加载的动态库:
由此可见,LiparyLoader类的loadAlreadyLocked用于加载的动态库正是Chromium动态库。由于此动态库已在前面加载过,再次调用System类的loadLibrary函数时,仅会触发JNIOnLoad函数,不会再次加载。Chromium动态库中的JNIOnLoad在调用时将进行初始化工作:
其中一项初始化操作是为Chromium的Content层设置名为AwMainDelegate的Main Delegate,该对象位于Chromium的androidwebview模块中。Android WebView通过Chromium的androidwebview模块来加载及渲染网页,而Chromium的加载与渲染功能由Content层实现,所以androidwebview模块通过Content层实现网页的加载与渲染。通过调用SetContentMainDelegate函数为Content层设置Main Delegate,以便它们可以互相通信。
综合分析可得,delegate参数指向AwMainDelegate对象,SetContentMainDelegate函数会将该对象保存在全局变量gcontentmain_delegate中。此步骤完成后,Chromium动态库已在App进程中加载并完成初始化,同时系统也为App进程创建了一个WebViewChromiumFactoryProvider类型的WebViewFactory。回到WebView类的ensureProviderCreated函数,此时会通过创建的WebViewChromiumFactoryProvider类型的WebViewFactory的createWebView方法为当前WebView创建一个WebView Provider:
WebViewChromiumFactoryProvider类中的createWebView方法返回的WebView Provider是WebViewChromium类型。此WebView Provider将传递给WebView类的ensureProviderCreated函数,并保存在成员变量mProvider中。这样,当前创建的WebView得到了一个WebViewChromium类型的WebView Provider,以后可以通过这个WebView Provider利用Chromium来加载和渲染网页。
软件亮点
1、Google搜索应用在Android手机上为用户带来优质的网络搜索体验。
2、官方提供的搜索应用能够查找相关网页和本地内容。
3、内容包含应用程序、浏览器书签和历史记录、联系人姓名、音乐等信息。
更新日志
v137.0.7151.4版本
进行了少量错误修复和优化,更新体验更加顺畅,欢迎安装最新版本以体验改善!