corsswalk的研究和使用(一)

corsswalk作为一款优秀的开源web引擎,在当今碎片化严重的android中简直是广大开发者的福音,使用它代替webview来跑游戏速度可谓是杠杠的,具体的介绍可以参考文章:http://dev.yesky.com/24/39285024.shtml

仔细阅读上面推荐的文章,发现它的好处之后才有动力继续研究它。然后我总结一下
Tables正常版简化版Shared Modeembedded Mode
Android webview(x86)
Android webview(ARM)
Cordova Android(x86)
Cordova Android(ARM)

Embedded

In embedded mode packaging, each web app is bundled with the full Crosswalk runtime. Since the Crosswalk runtime needs an architecture-dependent native library, two Android apks need to be generated for embedded mode: one for targets with Intel architecture (x86) and another for ARM targets. The make_apk.py script used in this tutorial generates a package for each architecture by default, as explained above.

The advantage is that you can keep a tight dependency between Crosswalk and the application, so you can ensure that the correct Crosswalk version is used. (In shared mode, you would have to ensure that the user had the correct runtime version available.)

The disadvantage is that the generated apk is significantly larger, as it contains the whole Crosswalk runtime inside it.

Shared

In shared mode packaging, each web app is bundled with a thin layer of Java code which is architecture-independent. This produces a much smaller apk file. However, to run this shared mode application, a separate, architecture-dependent Crosswalk runtime also has to be installed on the target. Again, one runtime is required for each architecture (one for x86, one for ARM); but, unlike embedded mode, multiple applications can share this single runtime.

The advantage is that one Crosswalk runtime library can support multiple shared mode applications: valuable if you are using Crosswalk to deploy multiple applications on the same Crosswalk version, as it reduces the size of each application apk.

Another advantage is that you can upgrade the runtime for multiple applications by upgrading one shared Crosswalk runtime package. By contrast, in embedded mode, upgrading the runtime requires you to upgrade each application at the same time: so moving to a newer runtime for multiple applications means upgrading each of those applications separately.

The disadvantage is that you must distribute apks both for your web applications and for the Crosswalk runtime.


使用

介绍了这么多,接下来看看下载的crosswalk有什么东西。因为我使用的是简化版的arm。所以就以最新的简化版为例,打开crosswalk-webview-10.39.240.1-arm,发现大概12M的东西,在crosswalk-webview-10.39.240.1-arm\res\raw\libxwalkcore.so.armeabi_v7a这个文件大概占了8M多而且还是个压缩文件,楼主把他理解为runtime。然后在lib目录有个xwalk_core_library_java.jar,通过调用api里面的XWalkView(类似于webview)实现网页的加载。

导入Project之后,接下来就是使用。
首先必须要继承XWalkActivity抽象类

public class MainActivity extends XWalkActivity {

    private XWalkView xWalkView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        xWalkView = new XWalkView(this, this);
        //类似于webview.setWebViewClient(new WebViewClient());
        //XWalkView已经没有setWebChromeClient()方法,但是在XWalkResourceClient中多了个onProgressChanged回调方法。
        xWalkView .setResourceClient(new XWalkResourceClient(xWalkView ));
        //设置Ui回调
        walkView.setUIClient(new XWalkUIClient(walkView));
        setContentView(xWalkView);
    }

    //返回上个页面
    private void back(){
         if(xWalkView.getNavigationHistory().canGoBack())
                xWalkView.getNavigationHistory().navigate(Direction.BACKWARD, 1);
     }

    //抽象方法,当crosswalk初始化完成时才会执行该方法,允许XWalkView在此之前初始化,但是不允许它在此之前加载网页。
    //之前的版本load方法可以在crosswalk初始化之前调用,现在不行了
    @Override
    protected void onXWalkReady() {
        // webview加载网页是loadUrl("http://csdn.net");
        xWalkView.load("http://csdn.net", null);
    }
}

XWalkResourceClient类似WebViewClient,看看便知,上手极快 ,XWalkUIClient顾名思义,实现下打印个log就知道哪些情况会调用到了,


有没有发现一般情况下使用webview时是要调用getSettings()来设置使用js,读取本地设置等等功能,但是在XWalkView中这些都帮我们封装好了,所以导致了没有方法去获取XWalkSettings.但是如果想要设置XWalkView的资源缓存方式的话要怎么办,只能使用反射了。

    //设置加载缓存的方式,和WebView的设置方式其实差不多
    public void setCacheMode(XWalkView xw){
        try {
            Method _getBridge = XWalkView.class.getDeclaredMethod("getBridge");
            _getBridge.setAccessible(true);
            XWalkViewBridge xWalkViewBridge = null;
            xWalkViewBridge = (XWalkViewBridge)_getBridge.invoke(xw);
            XWalkSettings xWalkSettings = xWalkViewBridge.getSettings();
            if(NetWorkHelp.isWifiConnected(this)){
                xWalkSettings.setCacheMode(WebSettings.LOAD_DEFAULT);
            }else{
                xWalkSettings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
            }
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }

程序需要以下权限

    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>

实现原理

研究一下XWalkActivity 的实现原理,为什么要在Avtivity继承。

public abstract class XWalkActivity extends Activity {
    private XWalkActivityDelegate mActivityDelegate;

    /**
     * Run on the UI thread to notify the Crosswalk runtime is ready.
     */
    protected abstract void onXWalkReady();

    /**
     * Return true if the Crosswalk runtime is ready, false otherwise.
     */
    public boolean isXWalkReady() {
        return mActivityDelegate.isXWalkReady();
    }

    /**
     * Return true if running in shared mode, false otherwise.
     */
    public boolean isSharedMode() {
        return mActivityDelegate.isSharedMode();
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        Runnable cancelCommand = new Runnable() {
            @Override
            public void run() {
                finish();
            }
        };
        Runnable completeCommand = new Runnable() {
            @Override
            public void run() {
                onXWalkReady();
            }
        };
        mActivityDelegate = new XWalkActivityDelegate(this, cancelCommand, completeCommand);
    }

    @Override
    protected void onResume() {
        super.onResume();
        mActivityDelegate.onResume();
    }
}

XWalkActivity默认运行embedded mode ,当运行的app当中没有runtime的时候,或者包含的rumtime不符合cpu架构的时候,它将会切换为shared mode,就会查找手机上的安装好的runtime,当rumtime没有或者不匹配的时候,就会弹出个dialog提示用户去下载安装runtime,默认是到缺省的应用市场下载,我们可以在 Android manifest插入meta-data修改下载地址 android:name=”xwalk_apk_url” android:value=”http://host/XWalkRuntimeLib.apk”

在改抽象类中主要实例化XWalkActivityDelegate以及调用mActivityDelegate.onResume()。参数中的cancelCommand顾名思义就是接受到取消命令的时候调用的,一般第一次打开会解压Crosswalk runtime,可能是用于此。completeCommand 是runtime加载完成回调的方法,在此处调用load方法。

shared mode下没有runtime,提示用户下载

那XWalkActivityDelegate是怎么实现的

public class XWalkActivityDelegate
            implements DecompressListener, ActivateListener, XWalkUpdateListener {

    ......

    public XWalkActivityDelegate(Activity activity,
            Runnable cancelCommand, Runnable completeCommand) {
        mActivity = activity;
        mCancelCommand = cancelCommand;
        mCompleteCommand = completeCommand;
        //解压runtime的dialog管理类
        mDialogManager = new XWalkDialogManager(mActivity);
        //设置runtime更新的管理类,适用于Shared Mode下搜索不到合适runtime的时候
        mXWalkUpdater = new XWalkUpdater(this, mActivity, mDialogManager);
        //初始化
        XWalkLibraryLoader.prepareToInit(mActivity);
    }
    //activity的onresume状态下调用的方法
    public void onResume() {
        if (mIsInitializing || mIsXWalkReady) return;

        mIsInitializing = true;
        if (XWalkLibraryLoader.isLibraryReady()) {
            //激活runtime
            XWalkLibraryLoader.startActivate(this, mActivity);
        } else {
            //解压runtime
            XWalkLibraryLoader.startDecompress(this, mActivity);
        }
    }
}

上面就是启动XWalkView的两个主要方法,大概的意思明白,具体的实现就不说了,我已经看不懂了,感兴趣的话可以自己去github上看。

    /**
     * Prepare to start initializing before all other procedures.
     *
     * <p>This method must be invoked on the UI thread.
     */
    public static void prepareToInit(Activity activity) {
        XWalkCoreWrapper.handlePreInit(activity.getClass().getName());
    }
    /**
     * Return true if the Crosswalk runtime has already been initialized successfully either in
     * embedded mode or shared mode, false otherwise.
     */
    public static boolean isLibraryReady() {
        return XWalkCoreWrapper.getInstance() != null;
    }
/**
     * Start activating the Crosswalk runtime in background. The activation is not cancelable.
     *
     * <p>This method must be invoked on the UI thread.
     *
     * @param listener The {@link ActivateListener} to use
     */
    public static void startActivate(ActivateListener listener, Activity activity) {
        new ActivateTask(listener, activity).execute();
    }
/**
     * Start decompressing the Crosswalk runtime in background
     *
     * <p>This method must be invoked on the UI thread.
     *
     * @param listener The {@link DecompressListener} to use
     * @param context The context of the package that holds the compressed Crosswalk runtime
     */
    public static void startDecompress(DecompressListener listener, Context context) {
        new DecompressTask(listener, context).execute();
    }

上面可以看出既然XWalkActivity是这么实现了,那完全可以不继承它来单独实现

public class MainActivity extends Activity  {

    private XWalkView walkView;
    private final static float ANIMATION_FACTOR = 0.6f;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mActivityDelegate  = new XWalkActivityDelegate(this, cancelCommand, completeCommand);

        LinearLayout linearLayout = new LinearLayout(this);

        walkView = new XWalkView(this, this);

        linearLayout.addView(walkView, new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
        setContentView(linearLayout);

        WebView view = new WebView(this);
        view.setWebViewClient(new WebViewClient());
        view.setWebChromeClient(new WebChromeClient());

    }

     @Override
    protected void onResume() {

        super.onResume();
        mActivityDelegate.onResume();
    }

    Runnable cancelCommand = new Runnable() {
         @Override
         public void run() {
             finish();
         }
     };
     Runnable completeCommand = new Runnable() {
         @Override
         public void run() {
             onXWalkReady();
         }

        private void onXWalkReady() {
            // TODO Auto-generated method stub
            walkView.load("http://csdn.net", null);
        }
     };

个人理解,不喜勿喷,哈哈

  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值