始终对webview了解比较浅显,于是乎就打开AS查看webview的源码,首先先阅读前面的注释文档,虽说文档巴拉巴拉一大堆,可是很多作用还是很有用的,在这里我整理了几个觉得比较有用的点:
1.如果要支持缩放,那么height or width 被设置成WRAP_CONTENT 都是不可以的,这样可能会带来很多预料之外的问题.
2.webview会在destroy和横屏切换时候进行重新绘制
3.如果你的HTML或者video 内容需要全屏你需要让WebChromeClient实现如下两个方法:onShowCustomView,onHideCustomView,两者有任何一个没有实现都不是不可以的.
4.在使用webview时候我们推荐使用固定的宽高,WRAP_CONTENT,可能让webview尺寸计算错误.
5.webview的API基本上都委托给一个后台的WebViewProvider类的实例来处理.其继承自AbsoluteLayout方 便向后兼容.webview的方法都委托给provider的实现类来处理.
学习完文档,接着看内部类与接口:
1.WebViewTransport:在线程之间传递webview(具体使用场景目前还未详)
2.接口FindListener用来监控搜索结果
3.VisualStateCallback 可是状态的回调
4.PictureListener 用来监控图片的改变,已过期了
5.HitTestResult 用来处理点击类型的抽象类
6.PrivateAccess 用来构造 provider 以及让provider可以调用webview父类的方法.
看完了内部类,继续看变量
1.mProvider 这是webview 服务的提供者,webview的功能基本上托管给其来实现
2.mFindListener 用来记录查找进度
了解完内部类之后开始了解些,大致的方法以及webview的使用
首先看下构造方法,webview 共计7个构造方法但是最终都会调用
1.检查目标的sdk 版本是否高于18,
2.checkThread( ) 检查当前方法是否允许在主线程,如果不在主线程中,而且版本高于18怎么抛出 RuntimeException.(webview 所有跟界面有关的方法都需要调用checkThread)这个方法
3.创建webview的服务提供者.
4.服务webview服务提供者进行初始化工作.
5.开启缓存服务
这样以来webview就创建完毕了,然而学习webview的源码同时里面大多是类似这样的结构
可以看出来webview方法都已经托管给mProvider来实现,下面就分析一下mProvider这个神秘东西的来历吧.
首先查看mProvider的出处,
然后我继续看WebViewFactoryProvider 这个类,此类是服务提供者的工厂类,但是是个接口.
其中的createWebView方法返回一个WebViewProvider,这个类的介绍上说明:这个类是webview的主要入口,和实现,webview的代理类经常初始化相关类,后台服务必须实现这个类.然而WebViewProvider也是一个接口,Sdk中无法查看的到WebViewProvider的实现类.
于是我们回来看getFactory这个方法,
这个方法返回的是一个接口,然而接口并不能实例化,那么我们看一下WebViewFactory.getProvider();
这段代码核心的代码就是ClassproviderClass=getProviderClass();
getProviderClass这个方法通过反射获取WebViewProvider,实现类,然后通过实现类来生成provider的实现类,通过跟踪代码可以看到WebViewFactoryProvider的实现类是"com.android.webview.chromium.WebViewChromiumFactoryProvider";然而WebViewChromiumFactoryProvider这个类Sdk看不到,我打开Sdk文件在source文件中,/Users/zhouzheng/Library/Android/sdk/sources/android-22/com/android/webview/chromium这个目录下找到了WebViewChromiumFactoryProvider这个类,然后我们看一下实现方法.
在里面我们可以看到WebViewChromium 这个类,点进去我们发现
由此可以看出最终的服务提供者是chromium.webview 是一个服务,主要作用是负责处理HTML文件及URL,整个流程使用了静态工厂的方法,提供一个provider为webview提供,webview,并不需要知道如何实现这些方法. 服务提供者 这种模式极大的分离了实现.
由于工厂和提供者都是面向接口编程,那么我们只需要做不同的工厂实现,便可以产生出不同提供者,这种方式为版本兼容提供了很多便利性.