Android的使用V8没有的WebView [英] Android utilize V8 without WebView

查看:905
本文介绍了Android的使用V8没有的WebView的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我运动从Java执行的JavaScript。犀牛都非常好,这在桌面上,但回落到(慢)除preTED模式在Android(由于Dalvik的暂时无法执行Java字节code中的犀牛JIT编译)。

I'm exercising executing javascript from Java. Rhino works very well for this on desktop, but has to fall back to (slow) interpreted mode on Android (due to dalvik being unable to execute the Java bytecode the Rhino JIT compiles).

Android有其内置的JavaScript引擎,它通过JNI内部访问,并应该给比犀牛更好的性能V8;但是,我能找到访问它的唯一途径是间接地通过一个web视图。

Android has its built-in V8 javascript engine which is accessed internally via JNI and ought to give much better performance than Rhino; however, the only way I can find to access it is indirectly through a WebView.

不幸的是,的WebView需要上下文,崩溃,NPE与空的背景下,所以我无法甚至实例化一个虚拟的WebView仅仅执行code,并返回结果。我工作的性质并没有真正让我提供一个语境的WebView,所以我希望也许有一些东西我俯瞰。

Unfortunately, WebView requires a Context, and crashes with NPE with a null context, so I'm unable to even instantiate a dummy WebView to merely execute the code and return the result. The nature of my exercise doesn't really allow me to provide a Context for WebView, so I'm hoping perhaps there's something I'm overlooking.

其中一些V8Threads的并行运行,所以它不是一个真正可行的(据我所知)到的WebView添加到我的布局和隐藏它,因为我不相信一个单一的WebView可以在多个执行功能线程。

Several of these V8Threads run in parallel, so it's not really feasible (as far as I'm aware) to add a WebView to my layout and hide it, as I don't believe a single WebView can execute functions in multiple threads.

private class V8Thread extends Thread
{
    private WebView webView;
    private String source;

    private double pi;
    private int i, j;

    public V8Thread(int i, int j)
    {
        pi = 0.0;
        this.i = i;
        this.j = j;

        source = "";

        try {
            InputStreamReader isReader = new InputStreamReader(assetManager.open("pi.js"));
            int blah = isReader.read();
            while (blah != -1)
            {
                source += (char)blah;
                blah = isReader.read();
            }

            webView = new WebView(null);
            webView.loadData(source, "text/html", "utf-8");
            webView.getSettings().setJavaScriptEnabled(true);
            webView.addJavascriptInterface(this, "V8Thread");
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    public double getResult()
    {
        return pi;
    }

    @Override
    public void run() 
    {
        webView.loadUrl("javascript:Androidpicalc("+i+","+j+")");
    }
}

在理想情况下,必须有一些支持方法可以直接调用V8,或至少执行JavaScript的,而不需要实际的WebView,因为它似乎是一个相当笨重,令人费解的方法只运行JavaScript code。

Ideally there must be some supported way to call V8 directly, or at least execute javascript without requiring an actual WebView, as it seems a rather clunky and convoluted method just to run javascript code.

更新

我重新安排我的codeA位,虽然看不见这里要说的是我现在实例化的AsyncTasks对preExecute的V8Threads(),同时保持在doInBackground一切()。该人士$ ​​C $ C被读入前面的程序,所以它不是冗余重读每个线程。

I've rearranged my code a bit, though unseen here is that now I am instantiating the V8Threads on the AsyncTasks's onPreExecute() while keeping everything else in doInBackground(). The source code is read in earlier in the program, so it's not redundantly re-read for each thread.

由于现在V8Thread被实例化的UI线程,我可以通过它的当前画面的内容(我使用的片段,所以我不能只是通过它的this),因此它不再崩溃。

Because now the V8Thread is instantiated on the UI Thread, I can pass it the current view's Context (I'm using fragments so I can't just pass it "this"), so it no longer crashes.

private class V8Thread extends Thread
{
    private WebView webView;

    private double pi;
    private int i, j;

    public V8Thread(int i, int j)
    {
        pi = 0.0;
        this.i = i;
        this.j = j;

        source = "";

        webView = new WebView(v.getContext());
    }

    @SuppressWarnings("unused")
    public void setResult(String in)
    {
        Log.d("Pi",in);
    }

    public double getResult()
    {
        return pi;
    }

    @Override
    public void run()
    {
        webView.getSettings().setJavaScriptEnabled(true);
        webView.addJavascriptInterface(this, "V8Thread");
        webView.loadData(source, "text/html", "utf-8");
        //webView.loadUrl("javascript:Androidpicalc("+i+","+j+")");
        webView.loadUrl("javascript:test()");
        Log.d("V8Thread","Here");
    }
}

但是,在执行的时候,logcat的吐出%的误差线之一,JavaScript的code从不执行先布局后无法得到viewWidth。我完全知道线程火灾,是因为这里的日志发送消息。下面是在js code相关的测试()函数。

However, when executing, logcat spits out one per thread of the error "Can't get the viewWidth after the first layout" and the javascript code never executes. I know the thread fires completely, because the "Here" log message is sent. Here's the relevant test() function in the js code.

function test()
{
V8Thread.setResult("blah");
}

工作正常,嗒嗒应显示在logcat的四倍,但一直没有出现。可能是我的源$ C ​​$ C会读错,但我怀疑这一点。

Working correctly, "blah" should show up four times in logcat, but it never shows up. Could be my source code is read incorrectly, but I doubt that.

Scanner scan = new Scanner(assetManager.open("pi.js"));
while (scan.hasNextLine()) source += scan.nextLine();

唯一的其他东西我可以想像的是,由于上述这些错误,web视图从来没有真正得到各地执行JavaScript的。

The only other thing I can imagine is that due to these aforementioned errors, the webView never actually gets around to executing the javascript.

我还可以补充一点,pi.js只包含的JavaScript,HTML没有任何。但是,即使我把它包在短短足够的HTML它有资格作为一个网页,仍然没有运气。

I'll also add that pi.js contains only javascript, no HTML whatsoever. However, even when I wrap it in just enough HTML for it to qualify as a webpage, still no luck.

推荐答案

您可以创建通过其API的新V8引擎上下文,并用它来执行你的JavaScript,看看<一href="https://android.googlesource.com/platform/external/v8">https://android.googlesource.com/platform/external/v8 包括目录,其中包含两个C ++头文件。链接对libwebcore.so(从<编译href="https://android.googlesource.com/platform/external/webkit">https://android.googlesource.com/platform/external/webkit)通过NDK库,没什么特别的。

You can create a new V8 Context via its API and use that to execute your JavaScript, look into https://android.googlesource.com/platform/external/v8 include directory which contains two C++ header files. Link against the libwebcore.so (compiled from https://android.googlesource.com/platform/external/webkit) library via the NDK, nothing special.

v8::Persistent<v8::Context> context = v8::Persistent<v8::Context>::New(v8::Context::New());
context->Enter();

参见 https://developers.google.com/v8/get_started 的工作,并会在Android上。只要确保该设备实际上是附带了V8(一些较旧的设备附带JSC [JavaScript的核心])。

Refer to https://developers.google.com/v8/get_started which will work on Android. Just make sure the device actually ships with V8 (some older devices ship with JSC [JavaScript Core]).

这篇关于Android的使用V8没有的WebView的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆