放弃WebView使用Crosswalk做富文本编辑器.docx

上传人:b****7 文档编号:25237219 上传时间:2023-06-06 格式:DOCX 页数:16 大小:21.30KB
下载 相关 举报
放弃WebView使用Crosswalk做富文本编辑器.docx_第1页
第1页 / 共16页
放弃WebView使用Crosswalk做富文本编辑器.docx_第2页
第2页 / 共16页
放弃WebView使用Crosswalk做富文本编辑器.docx_第3页
第3页 / 共16页
放弃WebView使用Crosswalk做富文本编辑器.docx_第4页
第4页 / 共16页
放弃WebView使用Crosswalk做富文本编辑器.docx_第5页
第5页 / 共16页
点击查看更多>>
下载资源
资源描述

放弃WebView使用Crosswalk做富文本编辑器.docx

《放弃WebView使用Crosswalk做富文本编辑器.docx》由会员分享,可在线阅读,更多相关《放弃WebView使用Crosswalk做富文本编辑器.docx(16页珍藏版)》请在冰豆网上搜索。

放弃WebView使用Crosswalk做富文本编辑器.docx

放弃WebView使用Crosswalk做富文本编辑器

放弃WebView,使用Crosswalk做富文本编辑器

版权声明:

欢迎转载,但请保留文章原始出处作者:

GavinCT出处:

为什么放弃WebView

AndroidWebView做普通浏览还好,做富文本编辑器(执行js:

document.body.contentEditable=true;),常常会遇到各种奇葩的bug,而且很难修复。

尽管Google在版本迭代中不断修复bug,但依旧没法用它来做富文本编辑。

Kitkat的改变

Google为了加强WebView的功能,在Kitkat引入了Chromium内核。

但还是存在着编辑的bug。

我所知道的一个bug是:

Kitkat版WebView在删除Html标签时处理不好,例如标签,就无法删除。

点击删除时直接越过此元素,将光标定位在图片前方,对图片不做处理。

当然,这个bug在Android5.0修复了。

Lollipop新策略

AlthoughWebViewhasbeenbasedonChromiumsinceAndroid4.4,theChromiumlayerisnowupdatablefromGooglePlay.

AsnewversionsofChromiumbecomeavailable,userscanupdatefromGooglePlaytoensuretheygetthelatestenhancementsandbugfixesforWebView,providingthelatestwebAPIsandbugfixesforappsusingWebViewonAndroid5.0andhigher.

可见在Lollipop里,可以通过GooglePlay来更新Chromium内核。

但是问题来了:

国内容易更新么?

如果不是自动更新,用户会手动更新么?

当然GooglePlay是自动更新,那国内手机没有自己市场的厂商呢?

Lollipop以前的版本怎么办?

Lollipop目前只有很少用户可以更新。

探索新的富文本编辑方案

显然,即便是有了Lollipop的解决方案,但问题依然很多。

我们还是需要一个替代方案,来保证我们在所有的Android手机上表现一致。

这个方案就是在应用中集成Chromium。

由于自己编译Chromium的难度较大,于是转而寻找编译好的Chromium库来使用。

需要声明的是:

Chromium内核只能在Android4.0以上才能使用,之后提到的所有Chromium库都只能在4.0以上平台使用。

过渡方案

最初在寻找替代方案的时候,应该是2013年10月左右,找到了两个Chromium库:

chromeview

这个库封装的较好,但是有一个致命的bug是不能滚动。

README中声明:

Attemptingtoscrolltheview(byswipingafingeracrossthescreen)doesnotupdatethedisplayedimage.

However,internally,theviewisscrolled.

Thiscanbeseenbydisplayingastackofbuttonsandtryingtoclickonthetopmostone.

ThisissuemakesChromeViewmostlyunusableinproduction.

注:

这个库的README最新声明里面推荐了Crosswalk,作者还是很用心的。

android-chromium

这个库整体稳定,不存在上面的bug。

用它作为编辑器差不多一年,没有出现什么问题。

但在今年6、7月的时候,突然间发现在三星新出的几款平板上(搭载了Kitkat)表现为花屏,屏幕上出现了各种颜色的横条,无法进行编辑。

其他搭载了Kitkat的手机当时没有发现过什么问题。

这里说一下这个库,自从作者看到Kitkat使用Chromium后,作者就声明不再更新了,其实差不多一年前就已经不更新了。

这个库使用起来比较麻烦,需要自己再进行封装,甚至连onPageFinished都需要自己来做。

可以看到,上面的替代方案,到今年6、7月,实际上已经无法使用。

而且非组织维护的代码,通常都有些不可靠的意味。

于是不得不继续寻找替代方案。

终于在GoogleI/O上看到了希望——Crosswalk

Crosswalk入门

CSDN资讯:

Crosswalk的介绍Crosswalk官方地址

上面的链接可以看到Crosswalk的介绍,Crosswalk种种吹牛逼的描述我就不写了。

写一下我的使用感受:

不用费力搞什么自己封装了,直接像用WebView一样使用。

在使用android-chromium这个库时,不仅要自己封装API来方便使用,还要操心Chromium的初始化,甚至还需要在清单文件里写一堆关于Chromium的东西,用来帮助Chromium建立单独的进程(Crosswalk只会创建Chromium的线程,不需要独立进程)。

Crosswalk由组织维护,比个人维护强多了。

跟随最新的Chromium不断更新,js等不用担心有函数没法使用。

而且不断更新过程中,肯定也会修复以前存在的bug,稳定性也是不用担心的。

最新稳定版Crosswalk基于Chromium38编译。

注:

此库也可以配合Cordova(PhoneGap)使用。

OK,感受说完,上教程。

集成到应用中

下载zip包,解压后导入。

关联此Library。

在清单文件中写入下列权限

android:

name="android.permission.ACCESS_FINE_LOCATION"/>

android:

name="android.permission.ACCESS_NETWORK_STATE"/>

android:

name="android.permission.ACCESS_WIFI_STATE"/>

android:

name="android.permission.CAMERA"/>

android:

name="android.permission.INTERNET"/>

android:

name="android.permission.MODIFY_AUDIO_SETTINGS"/>

android:

name="android.permission.RECORD_AUDIO"/>

android:

name="android.permission.WAKE_LOCK"/>

android:

name="android.permission.WRITE_EXTERNAL_STORAGE"/>

注:

使用过程中,观察Logcat可以看到报需要蓝牙权限,可以不用管它,不添加蓝牙权限可以正常使用。

此外,使用XWalkView必须开启硬件加速。

XWalkViewneedshardwareaccelerationtorenderwebpages.Asaresult,theAndroidManifest.xmlofthecaller'sappmustbeappendedwiththeattribute"android:

hardwareAccelerated"anditsvaluemustbesetas"true".

android:

hardwareAccelerated:

Thedefaultvalueis"true"ifyou'veseteitherminSdkVersionortargetSdkVersionto"14"orhigher;otherwise,it's"false".

在清单文件Application中声明即可。

android:

name="android.app.Application"android:

label="XWalkUsers"

android:

hardwareAccelerated="true">

基本使用

Crosswalk中用来替代WebView的控件叫XWalkView。

layout文件写法

和其他自定义控件一样。

android:

id="@+id/activity_main"

xmlns:

android="

android:

layout_width="fill_parent"

android:

layout_height="fill_parent">

代码中使用

重中之重:

防止内存泄漏

和其他Android的控件不同,这个类需要监听系统事件。

例如:

生命周期、intent、Activityresult。

控件内置的Web引擎需要获取并处理这些信息。

并且当XWalkView不再需要使用的时候,在onDestroy方法中XWalkView必须显式的调用destroy方法,否则容易造成Web引擎的内存泄漏。

原文如下:

UnlikeotherAndroidviews,thisclasshastolistentosystemeventslikeapplicationlifecycle,intents,andactivityresult.Thewebengineinsidethisviewneedtogetandhandlethem.AndtheonDestroy()methodofXWalkViewMUSTbecalledexplicitlywhenanXWalkViewwon'tbeusedanymore,otherwiseitwillcausethememoryleakfromthenativesideofthewebengine.It'ssimilartothedestroy()methodofAndroidWebView.

这段文字来自XWalkView官方API文档。

奇怪的是官方的范例中并没有在意这些事情,直接像WebView一样使用,更没有使用destroy方法。

考虑到之前使用android-chromium库也是需要显式调用。

这里还是加上,避免内存泄漏。

importandroid.app.Activity;

importandroid.os.Bundle;

importorg.xwalk.core.XWalkView;

publicclassMyActivityextendsActivity{

privateXWalkViewmXWalkView;

@Override

protectedvoidonCreate(BundlesavedInstanceState){

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

mXWalkView=(XWalkView)findViewById(R.id.activity_main);

mXWalkView.load("http:

//crosswalk-project.org/",null);

}

@Override

protectedvoidonPause(){

super.onPause();

if(mXWalkView!

=null){

mXWalkView.pauseTimers();

mXWalkView.onHide();

}

}

@Override

protectedvoidonResume(){

super.onResume();

if(mXWalkView!

=null){

mXWalkView.resumeTimers();

mXWalkView.onShow();

}

}

@Override

protectedvoidonDestroy(){

super.onDestroy();

if(mXWalkView!

=null){

mXWalkView.onDestroy();

}

}

@Override

protectedvoidonActivityResult(intrequestCode,intresultCode,Intentdata){

if(mXWalkView!

=null){

mXWalkView.onActivityResult(requestCode,resultCode,data);

}

}

@Override

protectedvoidonNewIntent(Intentintent){

if(mXWalkView!

=null){

mXWalkView.onNewIntent(intent);

}

}

}

loadUrl去哪了?

上面的代码中其实已经剧透了,使用load方法即可。

//url

mXWalkView.load("http:

//crosswalk-project.org/",null);

//thisloadsafilefromtheassets/directory

mXWalkView.load("file:

///android_asset/index.html",null);

publicvoidload(Stringurl,Stringcontent)

Loadawebpage/appfromagivenbaseURLoracontent.Ifurlisnulloremptyandcontentisnullorempty,thenthisfunctionwilldonothing.Ifcontentisnotnull,loadthewebpage/appfromthecontent.Ifcontentisnotnullandtheurlisnotset,return"about:

blank"ificallinggetUrl().Ifcontentisnull,trytoloadthecontentfromtheurl.ItsupportsURLschemeslike'http:

','https:

'and'file:

'.ItcanalsoloadfilesfromAndroidassets,e.g.'file:

///android_asset/'.

Parameters

urltheurlforwebpage/app.

contentthecontentforthewebpage/app.Couldbeempty.

WebViewClient?

对应WebView的WebViewClient,XWalkView中有XWalkResourceClient。

mXWalkView.setResourceClient(newXWalkResourceClient(mXWalkView){

@Override

publicvoidonLoadFinished(XWalkViewview,Stringurl){

super.onLoadFinished(view,url);

}

@Override

publicvoidonLoadStarted(XWalkViewview,Stringurl){

super.onLoadStarted(view,url);

}

});

调用JavaScript

不像WebView一样获取setting设置setJavaScriptEnabled为true才能执行。

Crosswalk可以直接执行js。

mXWalkView.load("javascript:

document.body.contentEditable=true;",null);

当然,按照Kitkat引入的方式,使用evaluateJavascript方法也是可以的。

(大神们推荐)

JavaScript回调Java

定义js回调接口

publicclassJsInterface{

publicJsInterface(){

}

@JavascriptInterface

publicStringsayHello(){

return"HelloWorld!

";

}

}

Caution:

Ifyou'vesetyourtargetSdkVersionto17orhigher,youmustaddthe@JavascriptInterfaceannotationtoanymethodthatyouwantavailabletoyourJavaScript(themethodmustalsobepublic).Ifyoudonotprovidetheannotation,themethodisnotaccessiblebyyourwebpagewhenrunningonAndroid4.2orhigher.

From

备注:

这里的@JavaScriptInterface所在的包是importorg.xwalk.core.JavascriptInterface;

XWalkView设置JavaScript可用且绑定对象

//绑定

mXWalkView.addJavascriptInterface(newJsInterface(),"NativeInterface");

调用html执行JavaScript或直接执行Javascript调用Java

mXWalkView.load("file:

///android_asset/index.html",null);

index.html源码:

href="#"onclick="clicked()">SayHello

functionclicked(){

alert(NativeInterface.sayHello());

}

/script>

高级使用

调试

Kitkat开始,Android提供了和Chrome联调功能。

可以很方便的在Chrome中调试WebView中的代码。

Crosswalk使用Chromium内核当然也具备这个功能。

开启调试的语句如下:

//turnondebugging

XWalkPreferences.setValue(XWalkPreferences.REMOTE_DEBUGGING,true);

对于Crosswalk来说,这个设置是全局的。

使用动画或者设置隐藏可见注意

默认XWalkView不能使用动画,甚至setVisibility也不行。

XWalkViewrepresentsanAndroidviewforwebapps/pages.ThusmostofattributesforAndroidviewarevalidforthisclass.Sinceitinternallyusesandroid.view.SurfaceViewforrenderingwebpagesbydefault,itcan'tberesized,rotated,transformedandanimatedduetothelimitationsofSurfaceView.Alternatively,ifthepreferencekeyANIMATABLE_XWALK_VIEWissettoTrue,XWalkViewcanbetransformedandanimatedbecauseTextureViewisintentionallyusedtorenderwebpagesforanimationsupport.Besides,XWalkViewwon'tberenderedifit'sinvisible.

开启动画模式:

@Override

protectedvoidonCreate(BundlesavedInstanceState){

super.onCreate(savedInstanceState);

//ANIMATABLE_XWALK_VIEWpreferencekeyMUSTbesetbeforeXWalkViewcreation.

XWalkPreferences.setValue(XWalkPreferences.ANIMATABLE_XWALK_VIEW,true);

setContentView(R.layout.animatable_xwview_layout);

}

@Override

publicvoidonDestroy(){

super.onDestroy();

//ResetthepreferenceforanimatableXWalkView.

XWalkPreferences.setValue(XWalkPreferences.ANIMATABLE_XWALK_VIEW,false);

}

由于设置也像调试一样是全局的,在onDestroy时记得关闭。

暂停JStimer

html代码

html>Ascriptonthispagestartsthisclock:

id="demo">

 

varmyVar=setInterval(function(){myTimer();},1000);

functionmyTimer()

{

vard=newDate();

vart=d.toLocaleTimeString();

document.getElementById("demo").innerHTML=t;

}

/script>

>

/html>

XWalkView对应方法:

mButton.setOnClickListener(newOnClickListener(){

@Override

publicvoidonClick(Viewv){

if(mXWalkView!

=

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 经管营销 > 经济市场

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1