Crosswalk入门

上面的链接可以看到Crosswalk的介绍,Crosswalk种种吹牛逼的描述我就不写了。写一下我的使用感受:

  1. 不用费力搞什么自己封装了,直接像用WebView一样使用。      在使用android-chromium这个库时,不仅要自己封装API来方便使用,还要操心Chromium的初始化,甚至还需要在清单文件里写一堆关于Chromium的东西,用来帮助Chromium建立单独的进程(Crosswalk只会创建Chromium的线程,不需要独立进程)。
  2. Crosswalk由组织维护,比个人维护强多了。
  3. 跟随最新的Chromium不断更新,js等不用担心有函数没法使用。而且不断更新过程中,肯定也会修复以前存在的bug,稳定性也是不用担心的。

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

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

OK,感受说完,上教程。

集成到应用中

  1. 下载zip包,解压后导入。
  2. 关联此Library。
  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.CAMERA" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
    <uses-permission android:name="android.permission.RECORD_AUDIO" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

    注:使用过程中,观察Logcat可以看到报需要蓝牙权限,可以不用管它,不添加蓝牙权限可以正常使用。此外,使用XWalkView必须开启硬件加速。

    XWalkView needs hardware acceleration to render web pages. As a result, the AndroidManifest.xml of the caller's app must be appended with the attribute "android:hardwareAccelerated" and its value must be set as "true".

    android:hardwareAccelerated : The default value is "true" if you've set either minSdkVersion or targetSdkVersion to "14" or higher; otherwise, it's "false".

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

    <application android:name="android.app.Application" android:label="XWalkUsers"
    android:hardwareAccelerated="true">

基本使用

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

layout文件写法

和其他自定义控件一样。

<org.xwalk.core.XWalkView android:id="@+id/activity_main"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
</org.xwalk.core.XWalkView>

代码中使用

重中之重:防止内存泄漏

和其他Android的控件不同,这个类需要监听系统事件。例如:生命周期、intent、Activity result。

控件内置的Web引擎需要获取并处理这些信息。并且当XWalkView 不再需要使用的时候,在onDestroy方法中XWalkView必须显式的调用destroy方法,否则容易造成Web引擎的内存泄漏。

原文如下:

Unlike other Android views, this class has to listen to system events like application life cycle, intents, and activity result. The web engine inside this view need to get and handle them. And the onDestroy() method of XWalkView MUST be called explicitly when an XWalkView won't be used anymore, otherwise it will cause the memory leak from the native side of the web engine. It's similar to the destroy() method of Android WebView.

这段文字来自XWalkView官方API文档。奇怪的是官方的范例中并没有在意这些事情,直接像WebView一样使用,更没有使用destroy方法。考虑到之前使用android-chromium库也是需要显式调用。这里还是加上,避免内存泄漏。

   import android.app.Activity;
import android.os.Bundle; import org.xwalk.core.XWalkView; public class MyActivity extends Activity {
private XWalkView mXWalkView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mXWalkView = (XWalkView) findViewById(R.id.activity_main);
mXWalkView.load("http://crosswalk-project.org/", null);
} @Override
protected void onPause() {
super.onPause();
if (mXWalkView != null) {
mXWalkView.pauseTimers();
mXWalkView.onHide();
}
} @Override
protected void onResume() {
super.onResume();
if (mXWalkView != null) {
mXWalkView.resumeTimers();
mXWalkView.onShow();
}
} @Override
protected void onDestroy() {
super.onDestroy();
if (mXWalkView != null) {
mXWalkView.onDestroy();
}
} @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);
}
}
}

loadUrl去哪了?

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

// url
mXWalkView.load("http://crosswalk-project.org/", null); // this loads a file from the assets/ directory
mXWalkView.load("file:///android_asset/index.html", null);

public void load (String url, String content)

Load a web page/app from a given base URL or a content. If url is null or empty and content is null or empty, then this function will do nothing. If content is not null, load the web page/app from the content. If content is not null and the url is not set, return "about:blank" ifi calling getUrl(). If content is null, try to load the content from the url. It supports URL schemes like 'http:', 'https:' and 'file:'. It can also load files from Android assets, e.g. '        file:///android_asset/ '.

Parameters

url the url for web page/app.

content the content for the web page/app. Could be empty.

WebViewClient?

对应WebView的WebViewClient,XWalkView中有XWalkResourceClient。

mXWalkView.setResourceClient(new XWalkResourceClient(mXWalkView){
@Override
public void onLoadFinished(XWalkView view, String url) {
super.onLoadFinished(view, url);
}
@Override
public void onLoadStarted(XWalkView view, String url) {
super.onLoadStarted(view, url);
}
});

调用JavaScript

mXWalkView = (XWalkView) findViewById(R.id.activity_main);
XWalkSettings webSettings = mXWalkView.getSettings();
//Tells the WebView to enable JavaScript execution.
webSettings.setJavaScriptEnabled(true);

执行js

mXWalkView.load("javascript:document.body.contentEditable=true;", null);

当然,按照Kitcat引入的方式,使用evaluateJavascript方法也是可以的。(大神们推荐)

JavaScript回调Java

  1. 定义js回调接口

    public class JsInterface {
    public JsInterface() {
    }
    @JavascriptInterface
    public String sayHello() {
    return "Hello World!";
    }
    }

    Caution: If you've set your targetSdkVersion to 17 or higher, you must add the @JavascriptInterface annotation to any method that you want available to your JavaScript (the method must also be public). If you do not provide the annotation, the method is not accessible by your web page when running on Android 4.2 or higher.From developer.android.com

    备注:这里的        @JavaScriptInterface 所在的包是        import org.xwalk.core.JavascriptInterface;

  2. XWalkView设置JavaScript可用且绑定对象

    mXWalkView = (XWalkView) findViewById(R.id.activity_main);
    XWalkSettings webSettings = mXWalkView.getSettings();
    //Tells the WebView to enable JavaScript execution.
    webSettings.setJavaScriptEnabled(true);
    //绑定
    mXWalkView.addJavascriptInterface(new JsInterface(), "NativeInterface");
  3. 调用html执行JavaScript或直接执行Javascript调用Java

    mXWalkView.load("file:///android_asset/index.html", null);

    index.html源码:

    <a href="#" onclick="clicked()">Say Hello</a>
    <script>
    function clicked() {
    alert(NativeInterface.sayHello());
    }
    </script>

高级使用

调试

Kitcat开始,Android提供了和Chrome联调功能。可以很方便的在Chrome中调试WebView中的代码。

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

开启调试的语句如下:

  // turn on debugging
XWalkPreferences.setValue(XWalkPreferences.REMOTE_DEBUGGING, true);

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

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

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

XWalkView represents an Android view for web apps/pages. Thus most of attributes for Android view are valid for this class. Since it internally uses android.view.SurfaceView for rendering web pages by default, it can't be resized, rotated, transformed and animated due to the limitations of SurfaceView. Alternatively, if the preference key ANIMATABLE_XWALK_VIEW is set to True, XWalkView can be transformed and animated because TextureView is intentionally used to render web pages for animation support. Besides, XWalkView won't be rendered if it's invisible.

开启动画模式:

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); // ANIMATABLE_XWALK_VIEW preference key MUST be set before XWalkView creation.
XWalkPreferences.setValue(XWalkPreferences.ANIMATABLE_XWALK_VIEW, true); setContentView(R.layout.animatable_xwview_layout);
}
@Override
public void onDestroy() {
super.onDestroy(); // Reset the preference for animatable XWalkView.
XWalkPreferences.setValue(XWalkPreferences.ANIMATABLE_XWALK_VIEW, false);
}

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

暂停JS timer

html代码

<!DOCTYPE html>
<html>
<body> <p>A script on this page starts this clock:</p>
<p id="demo"></p> <script>
var myVar = setInterval(function(){ myTimer(); }, 1000); function myTimer()
{
var d = new Date();
var t = d.toLocaleTimeString();
document.getElementById("demo").innerHTML = t;
}
</script> </body>
</html>

XWalkView对应方法:

mButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (mXWalkView != null) {
if (!isPaused) {
// Pause JS timer
mXWalkView.pauseTimers();
isPaused = true;
mButton.setImageResource(android.R.drawable.ic_media_play);
} else {
// Resume JS timer
mXWalkView.resumeTimers();
isPaused = false;
mButton.setImageResource(android.R.drawable.ic_media_pause);
}
}
}
});

这也在防止内存泄漏,监听系统事件示例代码中提到过:

@Override
protected void onPause() {
super.onPause();
if (mXWalkView != null) {
mXWalkView.pauseTimers();
mXWalkView.onHide();
}
} @Override
protected void onResume() {
super.onResume();
if (mXWalkView != null) {
mXWalkView.resumeTimers();
mXWalkView.onShow();
}
}

历史记录

mPrevButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// Go backward
if (mXWalkView != null &&
mXWalkView.getNavigationHistory().canGoBack()) {
mXWalkView.getNavigationHistory().navigate(
XWalkNavigationHistory.Direction.BACKWARD, 1);
}
XWalkNavigationItem navigationItem = mXWalkView.getNavigationHistory().getCurrentItem();
showNavigationItemInfo(navigationItem);
}
}); mNextButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// Go forward
if (mXWalkView != null &&
mXWalkView.getNavigationHistory().canGoForward()) {
mXWalkView.getNavigationHistory().navigate(
XWalkNavigationHistory.Direction.FORWARD, 1);
}
XWalkNavigationItem navigationItem = mXWalkView.getNavigationHistory().getCurrentItem();
showNavigationItemInfo(navigationItem);
}
}); private void showNavigationItemInfo(XWalkNavigationItem navigationItem){
url = navigationItem.getUrl();// Get the url of current navigation item.
originalUrl = navigationItem.getOriginalUrl();// Get the original url of current navigation item
title = navigationItem.getTitle(); text1.setText(title);
text2.setText(url);
text3.setText(originalUrl);
}

自动视频暂停

// The web page below will display a video.
// When home button is pressed, the activity will be in background, and the video will be paused.
mXWalkView.load("http://www.w3.org/2010/05/video/mediaevents.html", null);

loadAppFromManifest

mXWalkView.loadAppFromManifest("file:///android_asset/manifest.json", null);

manifest.json

{
"name": "ManifestTest",
"start_url": "index.html",
"description": "Manifest test",
"version": "1.0.0"
}

声明

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

作者:GavinCT

出处:      http://www.cnblogs.com/ct2011/

Crosswalk入门的更多相关文章

  1. 【转】Crosswalk入门

    原文:https://www.mobibrw.com/2015/1934 Crosswalk是一款开源的web引擎.目前Crosswalk正式支持的移动操作系统包括Android和Tizen,在And ...

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

    版权声明: 欢迎转载,但请保留文章原始出处 作者:GavinCT 出处:http://www.cnblogs.com/ct2011/p/4100132.html 为什么放弃WebView Androi ...

  3. 【Hybrid】288- Hybrid App 应用开发中 9 个必备知识点复习

    前言 我们大前端团队内部 ?每周一练 的知识复习计划继续加油,本篇文章是 <Hybrid APP 混合应用专题> 主题的第二期和第三期的合集. 这一期共整理了 10 个问题,和相应的参考答 ...

  4. Hybrid App 应用开发中 9 个必备知识点复习(WebView / 调试 等)

    前言 我们大前端团队内部 ?每周一练 的知识复习计划继续加油,本篇文章是 <Hybrid APP 混合应用专题> 主题的第二期和第三期的合集. 这一期共整理了 10 个问题,和相应的参考答 ...

  5. Angular2入门系列教程7-HTTP(一)-使用Angular2自带的http进行网络请求

    上一篇:Angular2入门系列教程6-路由(二)-使用多层级路由并在在路由中传递复杂参数 感觉这篇不是很好写,因为涉及到网络请求,如果采用真实的网络请求,这个例子大家拿到手估计还要自己写一个web ...

  6. ABP入门系列(1)——学习Abp框架之实操演练

    作为.Net工地搬砖长工一名,一直致力于挖坑(Bug)填坑(Debug),但技术却不见长进.也曾热情于新技术的学习,憧憬过成为技术大拿.从前端到后端,从bootstrap到javascript,从py ...

  7. Oracle分析函数入门

    一.Oracle分析函数入门 分析函数是什么?分析函数是Oracle专门用于解决复杂报表统计需求的功能强大的函数,它可以在数据中进行分组然后计算基于组的某种统计值,并且每一组的每一行都可以返回一个统计 ...

  8. Angular2入门系列教程6-路由(二)-使用多层级路由并在在路由中传递复杂参数

    上一篇:Angular2入门系列教程5-路由(一)-使用简单的路由并在在路由中传递参数 之前介绍了简单的路由以及传参,这篇文章我们将要学习复杂一些的路由以及传递其他附加参数.一个好的路由系统可以使我们 ...

  9. Angular2入门系列教程5-路由(一)-使用简单的路由并在在路由中传递参数

    上一篇:Angular2入门系列教程-服务 上一篇文章我们将Angular2的数据服务分离出来,学习了Angular2的依赖注入,这篇文章我们将要学习Angualr2的路由 为了编写样式方便,我们这篇 ...

随机推荐

  1. QTbaWidget控件几个例程 【worldsing笔记】

    Qt Creator自带的 QTabWidget控件几个例程 在Qt Windos版本安装后,在Example目录可以找到与QTabWidget相关的工程Demo,如果按默认安装的话他们分别是:   ...

  2. HDU 5828 Rikka with Sequence (线段树+剪枝优化)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5828 给你n个数,三种操作.操作1是将l到r之间的数都加上x:操作2是将l到r之间的数都开方:操作3是 ...

  3. C# Devexpress学习--LabelControl

    A LabelControl can display an image (regular or animated GIF file). Different images can be provided ...

  4. VS2010 远程调试

    1.在客户端电脑建一个账户,账户名和密码和调试端的账户密码一样 2.在客户端电脑进入 管理工具-本地安全策略-本地策略-安全选项 网络访问:本地账户的共享和安全模式”,改为“经典-本地用户以自己的身份 ...

  5. 使用XCopy发布网页

    链接:https://documentation.devexpress.com/#eXpressAppFramework/CustomDocument113245 In this lesson, yo ...

  6. 5分钟内使用React、Webpack与ES6构建应用

    http://blog.leapoahead.com/2015/09/12/react-es6-webpack-in-5-minutes/

  7. Spring使用Cache、整合Ehcache

    http://haohaoxuexi.iteye.com/blog/2123030 Spring使用Cache 从3.1开始,Spring引入了对Cache的支持.其使用方法和原理都类似于Spring ...

  8. linux 源码编译(转)

    源代码的用处无非是以下两点;1、软件根据用户的需要加以定制;2、二次开发;注:要根据软件的许可证书约定为准,开发者许可二次开发才行;1、源码包的打包格式;源代码一般以file.tar.gz file. ...

  9. 拖动窗体FormBorderStyle属性为None的窗体移动

    winform窗体的样式很单一,不够漂亮,往往我们需要对窗体进行重写,但是我们又要保留在重写前窗体本身带的功能,例如拖动窗体的头进行移动之类的. 一下方式可以实现该方法: [DllImport(&qu ...

  10. Codeforces Round #181 (Div. 2) B. Coach 带权并查集

    B. Coach 题目连接: http://www.codeforces.com/contest/300/problem/A Description A programming coach has n ...