最近的项目中,有用到phonegap,并需要展示一些需要高效渲染的网页,同情况下,IOS跑起来轻松无比,但是Webview。。。。(泪奔),在焦头烂额的机型及版本适配中,发现了Crosswalk项目。
一、 在使用 Crosswalk框架之前,我们必须得了解 Crosswalk
- Crosswalk是一款开源的Web引擎,其基于 Chromium/Blink 的应用运行环境,对于混合开发的轻量级应用尤为受欢迎。
- crosswalk官网 https://crosswalk-project.org/index_zh.html,很贴心的中文选项
-
同时在使用前的声明,如果你不能承受APK激增 20M~ OR 40M~ 体积的话,你懂得。当然如果大家有好的APK瘦身方法,希望能得到指点。
-
最近搞项目有尝试过许多框架,这里Tencent X5也非常棒,至于ChromiumView貌似不再维护了
二、开始应用到项目
题主先阶段给出为嵌入模式Xwalkview api使用介绍,crosswalk有支持phonegap的插件替换其中SystemWebview,以获取更强大功能,这个后续有时间会再次分享
-
首先在greadle 中声明 maven仓库,并添加库的依赖
repositories { maven { url 'https://download.01.org/crosswalk/releases/crosswalk/android/maven2' } } compile 'org.xwalk:xwalk_core_library:18.48.477.13'
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
-
接下来使用的XwalkView我们有几点注意的地方
1. 要求最低版本 minSdkVersion 14 2. 硬件加速:android:hardwareAccelerated="true" 3. 权限要求: <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> 4.<org.xwalk.core.XWalkView android:id="@+id/xw" xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent"> </org.xwalk.core.XWalkView>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
三、API使用
-
XWalkPreferences配置 api文档
//添加对javascript支持 XWalkPreferences.setValue("enable-javascript", true); //开启调式,支持谷歌浏览器调式 XWalkPreferences.setValue(XWalkPreferences.REMOTE_DEBUGGING, true); //置是否允许通过file url加载的Javascript可以访问其他的源,包括其他的文件和http,https等其他的源 XWalkPreferences.setValue(XWalkPreferences.ALLOW_UNIVERSAL_ACCESS_FROM_FILE, true); //JAVASCRIPT_CAN_OPEN_WINDOW XWalkPreferences.setValue(XWalkPreferences.JAVASCRIPT_CAN_OPEN_WINDOW, true); // enable multiple windows. XWalkPreferences.setValue(XWalkPreferences.SUPPORT_MULTIPLE_WINDOWS, true);
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
-
一些基本的api和webview类似
//设置滑动样式。。。 Xwalkview mXwview.setHorizontalScrollBarEnabled(false); mXwview.setVerticalScrollBarEnabled(false); mXwview.setScrollBarStyle(XWalkView.SCROLLBARS_OUTSIDE_INSET); mXwview.setScrollbarFadingEnabled(true); //获取setting mMSettings = mXwview.getSettings(); //支持空间导航 mMSettings.setSupportSpatialNavigation(true); mMSettings.setBuiltInZoomControls(true); mMSettings.setSupportZoom(true);
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
-
加载
mXwview.load(url, null); mXwview.setDrawingCacheEnabled(false);//不使用缓存 mXwview.getNavigationHistory().clear();//清除历史记录 mXwview.clearCache(true);//清楚包括磁盘缓存
- 1
- 2
- 3
- 4
- 5
-
XWalkView没了webview的setwebviewclient api 增加了setUIClient 和setResourceClient
顾名思义,UI变化及资源加载- 我们可以在XWalkUIClient中覆盖方法onPageLoadStarted及onPageLoadStopped处理页面开始加载及加载完毕
-
同时在页面缩放onScaleChanged或调用JsAlert中进行相应操作
mXwview.setUIClient(new XWalkUIClient(mXwview) { @Override public void onPageLoadStarted(XWalkView view, String url) { super.onPageLoadStarted(view, url); } @Override public boolean onJsAlert(XWalkView view, String url, String message, XWalkJavascriptResult result) { return super.onJsAlert(view, url, message, result); } @Override public void onScaleChanged(XWalkView view, float oldScale, float newScale) { if (view != null) { view.invalidate(); } super.onScaleChanged(view, oldScale, newScale); } @Override public void onPageLoadStopped(XWalkView view, String url, LoadStatus status) { super.onPageLoadStopped(view, url, status); } });
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
-
在XWalkResourceClient中同样有我们熟悉的onReceivedLoadError()错误回调及shouldOverrideUrlLoading()方法,同时相比webview增加的有shouldInterceptLoadRequest,可以对url进行监听及拦截操作
mXwview.setResourceClient(new XWalkResourceClient(mXwview) { @Override public void onReceivedLoadError(XWalkView view, int errorCode, String description, String failingUrl) { super.onReceivedLoadError(view, errorCode, description, failingUrl); } @Override public WebResourceResponse shouldInterceptLoadRequest(XWalkView view, String url) { LogUtils.d("http", "shouldOverrideUrlLoading-url=" + url); return super.shouldInterceptLoadRequest(view, url); } @Override public boolean shouldOverrideUrlLoading(XWalkView view, String url) { if(!url.contains("&platform=android-app")){ url= url + "&platform=android-app"; } obtainUploadUrl = url; return super.shouldOverrideUrlLoading(view, url); } });
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
-
监听back按钮点击事件
//改写物理按键——返回的逻辑 @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { if (mXwview.getNavigationHistory().canGoBack()) { mXwview.getNavigationHistory().navigate(XWalkNavigationHistory.Direction.BACKWARD, 1);//返回上一页面 } else { /*finish();*/ } return true; } return super.onKeyDown(keyCode, event); }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
-
同时不忘XWalkView令人心动的一点,与Activity生命周期的绑定,对资源的更好回收和处理
@Override protected void onDestroy() { // TODO Auto-generated method stub super.onDestroy(); if (mXwview != null) { mXwview.onDestroy(); } android.os.Process.killProcess(android.os.Process.myPid()); } @Override protected void onPause() { super.onPause(); if (mXwview != null) { mXwview.pauseTimers(); mXwview.onHide(); } } @Override protected void onResume() { super.onResume(); if (mXwview != null) { mXwview.resumeTimers(); mXwview.onShow(); } } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (mXwalkView != null) { mXwalkView.onActivityResult(requestCode, resultCode, data); } } @Override protected void onNewIntent(Intent intent) { if (mXwalkView != null) { mXwalkView.onNewIntent(intent); } }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
-
js调java
public class JsInterface { public JsInterface() { } @JavascriptInterface public String sayHello() { return "Hello World!"; } }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-
cookies使用
XWalkCookieManager xm = new XWalkCookieManager(); xm.setAcceptCookie(true); xm.setCookie(url, cookie);
- 1
- 2
- 3
- 4
- 5
- 6
四、好的,做好这一步,让我们来混淆打包吧
混淆:
-keep class org.xwalk.core.** { *;}
-keep class org.chromium.** { *;}
-keepattributes **
以上是其官网提高,但打包时仍存在问题,添加下方后解决
-keep class junit.framework.**{*;}
- 1
- 2
- 3
- 4
- 5
- 6
哟哟哟,切克闹
- 接下来会发现,apk大了40M~有木有,让我们打开apk
- Arm和X86多出来的两天.so动态库,每个大概占了20m大小,这边官方推荐的是分别打包上传到谷歌市场,不同用户手机处理器下载不同版本,但是这边项目非上线版的,故而没有去选择
-
当然,还有官网共享模式可以选择
-
分别打包时,在gradle中声明即可
productFlavors { armv7 { ndk { abiFilters "armeabi-v7a" } } x86 { ndk { abiFilters "x86" } } } 依赖中添加(可去官网下载不同版本库导入即可) X86Compile project '' Armv7Compile project ''