Android webkit简介及开发遇到的一些问题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
Android webkit简介
目录
1、webkit架构 (3)
2、Application (3)
2.1 WebViewClient里面几个重要方法 (4)
2.2 WebChromeClient里面几个重要的方法 (4)
2.3 使用webview的基本流程 (4)
2.4 使用webview的扩展流程 (5)
3、Webkit(framework) (7)
3.1 webkit(framework)流程的介绍 (7)
3.2 webkit(framework)的一些扩展功能的修改: (13)
4、Webkit(external) (16)
4.1 从文件管理器上传文件到邮箱附件里 (17)
4.2 修改webview上的复制效果 (18)
4.3 扩展WML的支持 (19)
4.4 调试 (19)
5、浏览器开发过程中的一些调试手段 (20)
1、webkit架构
目前Android平台自带的浏览器都是以webkit作为解析处理核心的,能够较好的使用webkit提供的功能,能够帮忙我们优化浏览器的一些功能和体验。
从架构上来看,android中的webkit的架构先可以划分为三个主要的部分。
如图1-1,application对应的主要是使用webview等实现相应功能的应用,这块目前主要是浏览器或者其他三方应用。
Webkit(framework)主要是作为对底层Webkit封装,并为应用提供一些显示方面扩展的功能。
Webkit(external)则是整个webkit的核心部分,负责对页面的解析和显示排版等处理。
图1-1 android中webkit架构流程
2、Application
针对普通的应用开发者来说,并不需要知道webkit的实现流程,以及怎么去修改framework中的webkit。
一般只需要知道怎么去使用webkit就可以达到自己想要的功能了。
Android平台为开发者提供了webview等相应的组件来使用webkit的相应功能。
下面就介绍下webview的使用和需要注意的一些地方。
Webview是继承了viewgroup的android提供的一些基本view之一,通过使用webview 可以加载本地或者网络服务器上的html等一些页面。
而通常我们会和webview配合使用的WebViewClient和WebChromeClient。
2.1 WebViewClient里面几个重要方法
onPageStarted:页面开始加载时会调用,用户可以在这个回调里面显示进度条以及一些初始操作。
onPageFinished:页面加载完毕时调用,可以在这个回调里面刷新界面。
shouldOverrideUrlLoading:需要用户是否针对这个url需要做特殊处理,在这个回调里面,可以对wtai协议或者其他一些特殊的url进行特殊的处理。
另外,如果想要让所有点击的link都在当前窗口打开,则一般需要在这个回调里面这样做。
在这个回调里面如果返回true的话,webkit就认为用户以及处理过了,就不会再进行处理了。
如果返回false,webkit会根据已有的逻辑进行处理。
如打开新的窗口加载这个url等操作。
2.2 WebChromeClient里面几个重要的方法
onProgressChanged:在加载进度有变动的时候会调用这个函数,所以可以在这个函数里面更新加载进度条。
onCreateWindow:在这个回调里面创建窗口
onGeolocationPermissionsShowPrompt:在这个回调里面会提示是否允许使用位置信息openFileChooser:在这个回调里面要求用户调用打开文件选择来选择文件
2.3 使用webview的基本流程
在使用webview的应用里面,首先创建一个webview,然后根据自己应用的需要添加WebViewClient或者WebChromeClient监听对象来实现一些界面上或者流程上的修改。
如:
创建好这些后,通过webview的loadurl就可以加载网络上的数据或者本地数据了。
如;
互联网用:webView.loadUrl("");
本地文件用:webView.loadUrl("file:///android_asset/XX.html");
使用的地方需要注意的有:
(1)如果是要加载网络服务器上的内容,则必须在应用的AndroidManifest.xml中使用许可"android.permission.INTERNET",如Browser等类似的应用。
如果只
是加载本地文件系统里面的文件,则可以不需要声明这个权限,如
Htmlviewer。
(2)如果用webview点链接看了很多页以后,如果不做任何处理,点击系统“Back”
键,整个浏览器会调用finish()而结束自身,如果希望浏览的网页回退而不是
退出浏览器,需要在当前Activity中处理并消费掉该Back事件。
2.4 使用webview的扩展流程
在上面简单介绍了使用webview的一些流程,通过这些流程,普通的应用可以完全满足需要了。
由于浏览器需要其他等比较丰富的功能和支持,所以需要比较复杂的处理流程。
下面就介绍下这些扩展的处理流程。
(1)shouldOverrideUrlLoading里面对特殊的url以及用户的一些操作的处理。
针对需要重新加载的url,需要浏览器这边区别处理。
目前需要单独处理的主要有下面几类:Wtai协议对应的url,WTAI 全称Wireless Telephony Applications Interface。
通过WTAI协议可以调用本地的电话簿、信息等模块做相应的功能。
如:在WML中可以调用设备的WTAI函数来呼叫特定的电话号码(最常用的功能之一),代码如下所示:<go href="wtai://wp/mc;$(phone_no)"/>通过解析这些信息可以呼叫phone_no对应的号码。
如果有兴趣,可以找下wtai协议来看看就知道了。
是由其他应用处理的url,如smsto:10657532521027?body=51,则通过startActivity 启动相应的Activity来处理这个url。
由于一些网页,常见的如电脑版之类的页面,打开新的url是要求在新窗口打开的,在打开前,webkit会调用shouldOverrideUrlLoading。
如果需求是要求可以选择其他浏览器来打开这个新的url,则一般是通过startActivityIfNeeded来启动选择浏览器的界面。
由于我们目前的需求是要求不能弹出选择框,直接用本地的浏览器打开。
针对这种需求,我们可以通过加判断ACCEPTED_URI_SCHEMA.matcher(url).matches(),判断当前的url是否可以被浏览器处理,如果可以则直接返回false。
返回false表示需要webkit来处理这个url,这个时候webkit就会根据当前的流程来处理,如打开一个新的窗口加载这个url 等操作。
(2)获取网页的缩略图。
在我们开发的过程中,会有需求要求我们获取网页的缩略图给用户显示。
就如我们目前的需求里面需要获取缩略图在多窗口切换的时候使用,以及在快捷方式里面使用。
获取缩略图的方式可以通过webview中的capturePicture来抓去当前浏览页面的截图,抓取后就根据自己的需要存储下来(目前浏览器是存储在数据库中)。
在抓取缩略图的时机可以有多种方式:1、可以在onPageFinished里抓取;2、可以通过webview里面的setPictureListener设置PictureListener,当页面的图片有变动时会调用这个函数,可以在这个函数中抓取缩略图(由于生成缩略图需要的时间比较长,为了在这个函数里面尽快返回,浏览器里面采用sendmessage到BrowserActivity里面来处理生成缩略图的流程)。
(3)在浏览器里面触发添加下载项。
在webview的使用过程中,遇到一些下载的地址时,如果我们要求下载这些内容,则必须创建一个DownloadListener,并且通过webview里面的setDownloadListener设置到webkit中实现对下载的监听。
如果遇到需要下载的url,则会调用到DownloadListener中的onDownloadStart。
开发者如果需要实现下载文件的功能,就在onDownloadStart里面添加对下载的支持。
关于下载这块,目前android是有一个下载管理的应用,其他应用在向DownloadProvider插入下载项后就完全可以开始正常的下载。
(4)在网页中复制文字。
在webview中长按键可以将webview置为复制状态,这个时候就可以根据自己的需要选择相应的文本。
但是如果我们需要一种方式:不需要在webview 上长按键就可以调出复制效果。
其中webview中的emulateShiftHeld函数就提供给了我们这样的功能,调用emulateShiftHeld这个函数就可以直接让webview进入复制状态,达到我们要求的效果。
关于修改webview中的复制效果后续我们会继续讨论。
(5)在webview上查找对应的文本。
在网页上查找相应的文本是比较有用的一个功能,webview同样给我们提供了这样一组接口来实现相应的功能。
首先,通过setFindIsUp(true)设置查找的标记位为true。
然后通过webview中的findAll查找出想要查找的文本,然后通过findNext来向上或者向下跳转查找的文本(findNextd中的参数为true或者false来实现向下或者向上)。
最后查找结束时,需要通过setFindIsUp(flase)把查找的标记位设置为false。
(6)多窗口的创建和实现流程。
随着手机性能的提升,目前android 手机都是支持多窗口的功能。
而一些页面也是要求在新的窗口打开,以及提升用户体验,都需要实现多窗口的功能。
目前多窗口的实现是各个activity 自己来处理的,如浏览器里面的Tab 和TabControl,他们之间的逻辑关系图如下:
TabControl Tab
webview Tab webview
每个Tab 对应一个窗口,目前最多为8个窗口。
每个Tab 有一个webview WebChromeClient 和WebViewClient ,在处理流程上是相互独立的。
创建一个Tab 分两种方式:一种是用户主动创建一个新的Tab ,另外一种是页面要求在新窗口加载,属于被动创建新的Tab 。
3、Webkit(framework)
Android 中的webkit(framework)作为承上启下的一层,为应用提供了简单的webview 来实现页面的加载和显示,同时又作为封装真正解析和显示核心的存在。
通过下面这张关系图可以大概了解下webkit 整个流程。
webkit(framework)通过JNI 的接口调用webkit(external)来实现具体的加载和排版等相应操作。
反之,webkit(external)通过调用GetJMethod 来调用webkit(framework)中的函数实现向webkit(framework)回调。
3.1 webkit(framework)流程的介绍
了解了webkit(framework)在整个webkit的地位和流程后。
接下来就对webkit(framework)进行一个比较详细的介绍。
如下图,webkit(framework)几个主要的类的关系流程如下
WebView对象的生成主要涉及3个类CallbackProxy、WebViewCore以及WebViewDatabase。
其中CallbackProxy对象用于UI线程和WebCore线程交互功能,WebViewCore是WebKit的核心层,负责与C层交互以及WebKit模块C层类库初始化。
而WebViewDatabase为WebKit模块运行时缓存、数据存储提供支持。
下面对几个主要的类进行详细的说明下
1.WebView
WebView类是WebKit模块Java层的视图类,所有需要使用Web浏览功能的Android 应用程序都要创建该视图对象显示和处理请求的网络资源。
目前,WebKit模块支持HTTP、HTTPS、FTP以及javascript请求。
WebView作为应用程序的UI接口,为用户提供了一系列的网页浏览、用户交互接口,客户程序通过这些接口访问WebKit核心代码。
2.WebViewDatabase
WebViewDatabase是WebKit模块中针对SQLiteDatabase对象的封装,用于存储和获取运行时浏览器保存的缓冲数据、历史访问数据、浏览器配置数据等。
该对象是一个单实例对象,通过getInstance方法获取WebViewDatabase的实例。
WebViewDatabase是WebKit模块中的内部对象,仅供WebKit框架内部使用。
3.WebViewCore
WebViewCore 类是Java 层与C 层WebKit 核心库的交互类,客户程序调用WebView 的网页浏览相关操作会转发给BrowserFrame 对象。
当WebKit 核心库完成实际的数据分析和处理后会回调WebViweCore 中定义的一系列JNI 接口,这些接口会通过CallbackProxy 将相关事件通知相应的UI 对象。
4. CallbackProxy
CallbackProxy 是一个代理类,用于UI 线程和WebCore 线程交互。
该类定义了一系列与用户相关的通知方法,当WebCore 完成相应的数据处理,则会调用CallbackProxy 类中对应的方法,这些方法通过消息方式间接调用相应处理对象的处理方法。
详细的处理流程在下文中会具体分析。
5. WebViewClient
WebViewClient 类定义了一系列事件方法
,如果Android 应用程序设置了WebViewClient 派生对象,则在页面载入、资源载入、页面访问错误等情况发生时,该派生对象的相应方法会被调用。
6. WebChromeClient
WebChromeClient 类定义了与浏览窗口修饰相关的事件。
例如接收到Title 、接收到Icon 、进度变化时,WebChromeClient 的相应方法会被调用。
大概了解了上面几个类的作用和流程后,接下来我们先主要先看下几个主要的流程,方便我们理解整个webkit(framework)大概的流程。
我们先了解下几个比较重要的类的消息流程,如下图
Webview 和webviewcore 之前的交互一般是通过handler 处理消息来实现的,我们了解了这个大概的流程后对于我们解决一些问题很有帮助。
接下来,了解下我们先了解下关于加载的一个消息流程。
通过上图我们可以大概了解下了webkit的一个加载的消息流程。
在浏览器的开发过程中,我们一般情况下主要修改的是界面显示的效果,所涉及的文件主要为webview和webtextview这两个文件的处理流程。
关于这两块的扩展修改,在下面的文档里面有比较详细的讲述。
3.2 webkit(framework)的一些扩展功能的修改:
Webkit(framework)的扩展功能的修改目前主要涉及到显示上的修改,其中涉及的文件主要为webtextview和webview,以及其他扩展功能的修改。
下面就列出目前主要修改的一些内容。
1、UA的修改。
UA,即user agent,一般内容包含手机软硬件信息,以及手机浏览器的一些信息。
通过这些信息,服务器可以根据他们自己的适配给手机返回相应的数据。
在浏览器的开发过程中,会有遇到不少和这个相关的问题,所以这方面需要重视一下。
首先,介绍下目前常见UA的一种格式。
在目前feature phone上的UA比较类似,一般格式如下:
Nokia N70的UA:
NokiaN70/5.0635.2.5.3 Series60/2.8 Profile/MIDP-2.0 Configuration/CLDC-1.1
OPPO T9的UA:
"OPPO_T9/3.46/15 Release/2009.2.1 Platform/MTK Browser/Obigo/Q03C Profile/MIDP-2.0 Configuration/CLDC-1.1"
对比类似的feature phone手机的UA,我们可以发现,一般最开始的时候就会声明手机的公
司和型号。
在UA里面这个信息是很重要的,一般的服务器也只会去获取这个型号信息,而不会去管其他信息。
其中Release/2009.2.1是版本编号。
Platform/MTK是平台类型
Browser/Obigo/Q03C是浏览器类型
Profile/MIDP-2.0 Configuration/CLDC-1.1 是两个通用的版本信息。
而我们目前智能机的UA就不能照这个规范来了,智能机的UA是有自己的规范的,如果我们修改不当的话,会导致网站服务器给的数据并不适合我们手机,导致出现的一些问题。
比如,网站如果不能识别出手机是android智能手机,很有可能把给featurephone适配的页面发送到我们手机这边,而在这种条件下,有的适合手机是解析出错的。
这个后面会再说明。
目前Android通用的手机UA格式如下:
Mozilla/5.0 (Linux; U; Android 2.3.4; zh-cn; OPPOT703 Build/GRJ22) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1
其中在frameworks\base\core\oppo\res\values\Strings.xml
和frameworks\base\core\res\res\values\Strings.xml
都有定义这样的字符串
web_user_agent:
Mozilla/5.0 (Linux; U; Android %s)AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1
针对我们现有的android版本,这些信息一般是不需要修改的。
因为这些信息也就是对应的这个版本的android的信息。
我们主要的修改的是Android %s,这里面的%s是会拼接一些信息,主要修改的方面就是这些拼接的信息。
我们要先找到拼接这些信息的地方,在websettings.java有setUserAgentString这个方法,浏览器一般是通过这个来设置UA的,由于默认状况下,我们是采用的手机拼接的UA,所以这里的参数一般为null,这样我们通过setUserAgentString来设置UA时,就会采用默认拼接UA的流程。
就是通过getCurrentUserAgent来获取的,在这个函数里面就对UA的一些信息进行拼接,得到我们最终的UA。
目前OPPO的智能机有一个基本的规范,关于版本等信息一般是不用我们操心的(是从系统里面获取的版本信息,这个肯定是没问题的)。
需要关注的就是型号等信息,在getCurrentUserAgent中,我们是通过下面截图上的代码获取的手机型号。
由于Build.MODEL现在获取的只有手机的型号信息,如X903、T703等。
按照公司的规范是要加OPPO字段,所以这个地方需要做下拼接OPPO字段的处理。
最终得到我们目前T703的UA为
Mozilla/5.0 (Linux; U; Android 2.3.4; zh-cn; OPPOT703 Build/GRJ22) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1
在开发过程中,我们会遇到一些和UA相关的问题,针对这些问题这里进行分类说明下,以后遇到相关的问题也就好解决了。
(1)网站会根据不同的UA来返回不同的数据。
这个是我们经常会遇到的一些事情,如我们经常去用不同的手机去加载同样的地址,返回的页面却差别很大。
这就是网站服务器根据手机的UA来判断当前的手机的一个系统和性能。
像智能机等一些高端手机,页面包含的图片和布局信息就比较丰富,页面就很好看。
非智能机等一些手机,如A201等这些手机,给的页面就是普通的手机页面,页面包含的图片信息比较少,所需要的手机的配置也就低些。
(2)网站匹配手机型号的问题。
在访问一些网站时,网站会匹配手机的型号,如常见的一些3g这些站点下载应用时会匹配你的手机。
有的时候会发现手机型号偶尔会匹配错误,如之前E21W会被匹配成索爱的一款手机。
导致这种问题的出现是由于网站的匹配手机的信息库中没有这款手机的型号,同时匹配策略导致的匹配错误。
这种修改一般是需要同营销沟通让网站方面能够识别我们的手机。
(3)网站区别识别的问题。
在开发E21W的过程中,我们有遇到这样一个问题。
在访问的时候,我们手机被识别成电脑,而这个网站则要求终端必须是手机才能正常进行用户登陆。
当时推断是UA的问题,然后我们把手机的UA换成nokia 的后,完全可以正常登陆了。
经过最后的逐步确认,推断出mop识别UA的策略:首先会去识别手机的型号,如nokia、索爱、三星以及摩托罗拉这些知名厂商或者和他们有合作的厂商。
由于我们公司并没有和他们进行合作,所以很遗憾,我们的手机不被识别。
然后,如果是不能识别型号的手机,这个时候,他会去判断手机浏览器的类型。
当时测试了Obigo的手机浏览器是可以的,推断是因为国内大部分的厂商都用的MTK的平台,而MTK平台采用的浏览器类型为Obigo的,所以mop站点把这个浏览器类型给放过了。
而当时E21W采用的是ACCESS的浏览器,导致也完全无法识别。
像类似这样的问题,有两种途径:一种是营销去适配站点;另外一种就是修改UA,不过修改UA带来的问题就是UA是不标准的了。
(4)网关区别对待的问题。
在实际的开发中,我们通过网关去访问,偶尔会出现一些问题。
就是其他手机访问或者其他功能是正常的,但是我们的却是有问题。
在很多时候,合作方需要我们去换成另外功能是正常的手机的UA再进行测试。
在解决类似的问题过程中,经过咨询运营商的技术人员,他们回复一般不会针对UA进行区别处理。
但是很多时候为了排查问题,我们还是会进行这样替换UA的测试。
所以在开发的过程中,留下一个替换UA的简便方式能够帮我们尽快的验证这些问题。
通过上述对UA的一个大概的描述,可以对UA进行了一个初步的了解。
在实际的开发过程和解决问题的过程中,我们可以多留心下这块,能给我们带来比较快的解决问题的思路。
2、针对复制时的popupmenu的扩充。
按照公司对智能机的要求,需要在webview复制的时候,弹出复制的popupmenu。
目前这块的处理方案基本是参考的89的方案来做的,基本的流程是在view里面加入了新的pupmenu的实现,在webview里面按照要求调用得到的。
3、在webview上长按键进入复制状态。
这个的流程就比较简单了,由于webview是继
承于viewgroup的,所以可以直接在performlongclick里面调用setUpSelect进入复制状态。
随后的相应的复制流程根据需要在相应的事件处理函数里说明。
4、webview对放大镜的支持。
由于android默认的webview是不支持放大镜的,所以
如果实现这个功能,需要我们自己扩展。
这个扩展放大镜的功能,目前可以根据textview里面对于放大镜的使用来扩展。
需要注意的一些方面有:
(1)长按键时弹出放大镜和contextmenu之间的冲突关系
(2)放大镜和webtextview里面的放大镜和事件的冲突关系
5、webtextview扩展放大镜的效果。
由于默认的webtextview是不支持放大镜和文本
选择的。
即在isMagnifierAndTextSelectionEnabled直接返回false,textview在判断的时候就得到webtextview不支持这个功能。
由于需求的要求,我们是要在webtextview里面支持放大镜和文本选择的功能。
所以,可以针对这样进行修改:
其中,调用mWebView.isCanShowPopupMenu()来判断当时调用webview的是否是oppo 自己的应用。
这样可以来决定在三方应用上采用android默认的显示流程,避免不必要的一些问题的产生。
由于webtextview的放大镜在移动的时候会移动到webview的页面上,在交互上会出现一些bug,这就需要在webview做些处理解决这些bug。
4、Webkit(external)
Webkit(external)是整个webkit的核心,负责页面的加载和排版以及脚本等解析的工作。
目前IOS、android等系统都将webkit作为内置的浏览器解析和排版核心。
所以,了解webkit后会能够让我们足够深入了解整个android系统浏览器排版以及解析。
Webkit整体包含的代码比较多,首先我们先了解下它大概的一个架构。
整个webkit架构如图可以分为三部分:
1、webkit:webkit部分包含了很多不同平台对webkit封装的实现,即抽象出了能
直接与浏览器应用直接对应的一些概念的实现。
2、webcore:是整个webkit项目的核心,用来实现render引擎、解析web页面。
3、JavaScriptCore:是JavaScript的解释器。
Webkit(external)
Webkit
WebCore JavaScriptCore
关于webkit来说,目前了解的并不深入,所以这个地方主要还是讲下在实际修改中的一些问题,以及调试这些webkit的方法。
4.1 从文件管理器上传文件到邮箱附件里
由于android默认是没有文件管理器的,所以在webkit里面并不支持从文件管理器里面选择文件上传。
这就需要我们修改android webkit的流程,能够实现从文件管理器里面正常上传文件。
首先,根据WebChromeClient中的openFileChooser来找到最终调用处-WebViewCore。
在WebViewCore 的openFileChooser函数中,我们可以看到如下图所示,获取的路径是从数据库里面查找出的相应文件的名字,最终拼接成为一个全路径。
列入url为content://media/external/images/media/54的在查找数据库后就可以得到54对应的文件的名字,最终拼接成为一个路径。
而通过文件管理器获得的url,在传递进来已经是一个全路径了,比如:file:///mnt/sdcard/DUOMI/music/Lydia_F.I.R.mp3就是指存在T卡上的一首歌曲。
所以在这个地方,我们可以直接返回这个路径。
在这个函数前面加上如下处理代码
关于路径的获取处理完后,我们需要考虑的external/webkit里面对这个的处理。
根据MTK的工程师的帮助,我们需要修改的文件为:
external/webkit/WebKit/android/jni/WebCoreFrameBridge.cpp中的uriFromUriFileName来对file://类型的url进行特殊处理。
修改代码如下:
4.2 修改webview上的复制效果
Webview中可以选择文本以及获取相应的文本达到复制的功能。
但在实际开发过程中,我们需要修改webview的复制的效果,这就需要我们针对webview的选择文本以及复制有一个比较清楚的了解。
目前复制效果指的主要是复制起始图标和终止图标,以及复制的popupmenu。
首先,我们先了解下这个复制效果的流程。
android默认的复制效果的实现全部是在external/webkit里面通过SkCanvas采用代码来绘制的一个效果,并不是贴图得到的效果。
这就要求如果我们修改这种复制效果的话,有两种方式;
1、为修改绘制的代码,最终修改绘制的一个效果。
但是这种修改可能无法满足需要要
求的那种复制的效果,毕竟通过绘制要调整一些像素达到真正的效果需要不少工作量。
同时这种修改在需求变动时会很麻烦。
所以,这个方案不做优先考虑。
‘
2、另外一种方案就是把原有通过代码绘制的流程注释掉,重新做一套新的通过贴图来
实现的复制效果。
这样如果需求有变动我们就可以直接替换图片来达到效果。
所以,我们优先采用这种方案来实现我们的修改。
按照第二种方案来实现的话,由于目前我们修改的复制效果主要是复制区域的起始和终止图标。
按照修改的要求,我们有几个如下的流程:
(1)先把android原有的绘制起始和终止图标的代码注释掉,即在\external\webkit\WebKit\android\nav\SelectText.cpp中的drawSelectionRegion函数
里将绘制起始和终止的流程注释,如下图
(2)注释掉这个流程后,我们这个时候去复制,会发现复制的起始和终止图标消失了。
接下来就添加我们自己的复制效果的流程。
首先,在external/webkit里面添加nativeGetSelectionStartBounds和
nativeGetSelectionEndBounds来获取起始和终止的图标的位置,这样我们就可以知道在什么地方来绘制这些图标。
由于我们采用的不是修改绘制的代码,而是采用新的类似贴图的方案。
所以,为了实现这样的一个效果,我们就要在webview.java(framework/webkit)里面修改流程来显示这个起始和终止图标。
如下面的创建selector的流程图。
其中,创建的selector为SelectPopupWindow。
SelectPopupWindow是继承于PopupWindow,所以可以具有popupwindow的一些特性,能够显示在webview之上。
通过以上的流程我们就可以实现对复制的起始和终止图标的修改。
4.3 扩展WML的支持
由于android默认是不支持WML的,默认遇到WML的页面会当成text/plain来处理,导致wml的源码会直接显示到页面上。
所以如果要支持WML,则需要我们对目前的webkit 进行修改来支持wml格式的页面。
但是根据MTK工程师的反馈,由于WML的支持并不好,会导致出现一些crash的问题,有风险,需谨慎的扩展这种支持。
附件里面是扩展WML支持的方法。
4.4 调试
关于webkit的调试主要是.so文件的调试,目前有两种手段吧:
1、加log,这种调试手段主要是为了解决流程上的问题。
2、如果是.so文件出现异常了,需要根据最后抓到log里面的PC值得到最终的代码,这个
对应的流程在刘奇虎那篇文档上有比较详细。
我这边简单说明下一些事项吧:
如果两份代码是一样的话,那他们编译出的.so是完全一样的,所以如果是QT或者QE 出现的问题,如果你的.so对应的代码和QE对应版本.so的代码是一样的,就完全可以。