zoukankan      html  css  js  c++  java
  • 在Android上使用Google V8 JS 引擎

    cantk-runtime中直接使用的webview,通过JAVA扩展接口把Canvas的2d Context的API定向到JNI,通过OpenGL来图形加速,渲染速度大大提高。后来测试发现在大部分手机上都很正常,但是在有的老手机上速度不稳定,出现突然卡顿的情况。经过研究发现原因是老版本的webkit里没有requestAnimationFrame这个接口(或类似接口),用setTimeout来模拟的requestAnimationFrame非常不稳定。

    为了解决这个问题,我们决定像其它Runtime一样集成Google V8 JS引擎,自己模拟一个webview出来。架构也相当简单,上面用GLSurfaceView,在JNI里使用Google V8 JS引擎来JS代码,在onDrawFrame里去执行requestAnimationFrame注册的函数,经过测试性能相当稳定。

    Google V8 JS引擎在缺省情况下用起来非常顺手,它自带的例子拿来就可以用,比如:

    int main(int argc, char* argv[]) {
      v8::V8::InitializeICU();
      v8::Platform* platform = v8::platform::CreateDefaultPlatform();
      v8::V8::InitializePlatform(platform);
      v8::V8::Initialize();
      v8::V8::SetFlagsFromCommandLine(&argc, argv, true);
      ShellArrayBufferAllocator array_buffer_allocator;
      v8::V8::SetArrayBufferAllocator(&array_buffer_allocator);
      v8::Isolate* isolate = v8::Isolate::New();
      run_shell = (argc == 1);
      int result;
      {
        v8::Isolate::Scope isolate_scope(isolate);
        v8::HandleScope handle_scope(isolate);
        v8::Handle<v8::Context> context = CreateShellContext(isolate);
        if (context.IsEmpty()) {
          fprintf(stderr, "Error creating context
    ");
          return 1;
        }
        v8::Context::Scope context_scope(context);
        result = RunMain(isolate, argc, argv);
        if (run_shell) RunShell(context);
      }
      v8::V8::Dispose();
      v8::V8::ShutdownPlatform();
      delete platform;
      return result;
    }

    但是我需要在onSurfaceCreated做初始化的工作,在onDrawFrame里去执行JS。一个看似简单的改东却遇到了麻烦:Isolate::GetCurrent()返回值为空。第一次接触V8,对里面的概念理解不深,以为Isolate::Scope和HandleScope一样,在作用范围结束时释放Isolate,我希望onSurfaceCreated调用完成后Isolate对象还活着,在onDrawFrame还可以使用,所以去掉v8::Isolate::Scope isolate_scope(isolate)这行代码,但是结果Isolate::GetCurrent()返回值还是为空。

    网上没有找到类似的应用场景,于是去看V8的代码。发现Isolate::Scope的功能并不是想的那样。在Isolate::Scope的构造函数里调用Isolate::Enter把参数指定的isolate设置成当前的isolate(放在线程局部存储里的),在Isolate::Scope的析构函数调用Isolate::Exit恢复前一个isolate。只有在这个范围内Isolate::GetCurrent()才有效。

    知道原理后,修改很简单了:直接调用Isolate::Enter。

    cantk-runtime v8版本目前还不完善,不过欢迎大家加星:)

  • 相关阅读:
    CodeForces 492C Vanya and Exams (贪心)
    CodeForces 492A Vanya and Cubes
    如何设置 Windows 默认命令行窗口大小和缓冲区大小
    [MySQL] Data too long for column 'title' at row 1
    [转] Hibernate不能自动建表解决办法(hibernate.hbm2ddl.auto) (tables doesn't exist)
    CodeForces 489D Unbearable Controversy of Being (不知咋分类 思维题吧)
    Autofac官方文档翻译--二、解析服务--1解析参数传递
    Autofac官方文档翻译--一、注册组件--4组件扫描
    Autofac官方文档翻译--一、注册组件--3属性和方法注入
    Autofac官方文档翻译--一、注册组件--2传递注册参数
  • 原文地址:https://www.cnblogs.com/hzcya1995/p/13333019.html
Copyright © 2011-2022 走看看