Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> 在Android上使用Google V8 JS 引擎

在Android上使用Google V8 JS 引擎

編輯:關於Android編程

在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 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()才有效。

 

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved