Overview

JNI (Java Native Interface) is the mechanism that enables Java code to call native functions, and native code to call Java functions.

  • Native code calls into Java using apis from <jni.h>, which basically mirror Java's reflection APIs.
  • Java code calls native functions by declaring body-less functions with the native keyword, and then calling them as normal Java functions.

jni_generator generates boiler-plate code with the goal of making our code:

  1. easier to write, and
  2. typesafe.

jni_generator uses regular expressions to parse .Java files, so don't do anything too fancy. E.g.:

  • Classes must be either explicitly imported, or are assumed to be in the same package. To use java.lang classes, add an explicit import.
  • Inner classes need to be referenced through the outer class. E.g.: void call(Outer.Inner inner)

The presense of any JNI within a class will result in ProGuard obfuscation for the class to be disabled.

Exposing Native Methods

Without Crazy Linker:

  • Java->Native calls are exported from the shared library and lazily resolved by the runtime (via dlsym()).

With Crazy Linker:

  • Java->Native calls are explicitly registered with JNI on the native side. Explicit registration is necessary because crazy linker provides its own dlsym(), but JNI is hardcoded to use the system's dlsym().

    • The logic to explicitly register stubs is generated by jni_registration_generator.py.

      • This script finds all native methods by scanning all source .java files of an APK. Inefficient, but very convenient.
    • Since dlsym() is not used in this case, we use a linker script to avoid the cost of exporting symbols from the shared library (refer to //build/config/android:hide_all_but_jni_onload).
  • jni_registration_generator.py exposes two registrations methods:
    • RegisterNonMainDexNatives - Registers native functions needed by multiple process types (e.g. Rendereres, GPU process).
    • RegisterMainDexNatives - Registers native functions needed only by the browser process.

Exposing Java Methods

Java methods just need to be annotated with @CalledByNative. The generated functions can be put into a namespace using @JNINamespace("your_namespace").

Usage

Because the generator does not generate any source files, generated headers must not be #included by multiple sources. If there are Java functions that need to be called by multiple sources, one source should be chosen to expose the functions to the others via additional wrapper functions.

Calling Java -> Native

  • Methods marked as native will have stubs generated for them that forward calls to C++ function (that you must write).
  • If the first parameter is a C++ object (e.g. long mNativePointer), then the bindings will automatically generate the appropriate cast and call into C++ code (JNI itself is only C).

Calling Native -> Java

  • Methods annotated with @CalledByNative will have stubs generated for them.
  • Just call the generated stubs defined in generated .h files.

Java Objects and Garbage Collection

All pointers to Java objects must be registered with JNI in order to prevent garbage collection from invalidating them.

For Strings & Arrays - it's common practice to use the //base/android/jni_* helpers to convert them to std::vectors and std::strings as soon as possible.

For other objects - use smart pointers to store them:

  • ScopedJavaLocalRef<> - When lifetime is the current function's scope.
  • ScopedJavaGlobalRef<> - When lifetime is longer than the current function's scope.
  • JavaObjectWeakGlobalRef<> - Weak reference (do not prevent garbage collection).
  • JavaParamRef<> - Use to accept any of the above as a parameter to a function without creating a redundant registration.

Additional Guidelines / Advice

Minimize the surface API between the two sides. Rather than calling multiple functions across boundaries, call only one (and then on the other side, call as many little functions as required).

If a Java object “owns” a native one, store the pointer via "long mNativeClassName". Ensure to eventually call a native method to delete the object. For example, have a close() that deletes the native object.

The best way to pass “compound” types across in either direction is to create an inner class with PODs and a factory function. If possible, make mark all the fields as “final”.

Build Rules

  • generate_jni - Generates a header file with stubs for given .java files
  • generate_jar_jni - Generates a header file with stubs for a given .jar file
  • generate_jni_registration - Generates a header file with functions to register native-side JNI methods (required only when using crazy linker).

Refer to //build/config/android/rules.gni for more about the GN templates.

Changing jni_generator

  • Python unit tests live in jni_generator_tests.py
  • A working demo app exists as //base/android/jni_generator:sample_jni_apk

[Chromium文档转载,第007章]JNI on Chromium for Android的更多相关文章

  1. [Chromium文档转载,第003章]Proposal: Mojo Synchronous Methods

    Proposal: Mojo Synchronous Methods yzshen@chromium.org 02/02/2016 Overview Currently there are quite ...

  2. [Chromium文档转载,第002章]Mojo C++ Bindings API

    Mojo C++ Bindings API This document is a subset of the Mojo documentation. Contents Overview Getting ...

  3. [Chromium文档转载,第001章] Mojo Migration Guide

        For Developers‎ > ‎Design Documents‎ > ‎Mojo‎ > ‎ Mojo Migration Guide 目录 1 Summary 2 H ...

  4. [Chromium文档转载,第006章]Chrome IPC To Mojo IPC Cheat Sheet

    For Developers‎ > ‎Design Documents‎ > ‎Mojo‎ > ‎ Chrome IPC To Mojo IPC Cheat Sheet 目录 1 O ...

  5. [Chromium文档转载,第005章]Calling Mojo from Blink

    For Developers‎ > ‎Design Documents‎ > ‎Mojo‎ > ‎ Calling Mojo from Blink Variants Let's as ...

  6. [Chromium文档转载,第004章]Mojo Synchronous Calls

    For Developers‎ > ‎Design Documents‎ > ‎Mojo‎ > ‎ Synchronous Calls Think carefully before ...

  7. 用R创建Word和PowerPoint文档--转载

    https://www.jianshu.com/p/7df62865c3ed Rapp --简书 Microsoft的Office软件在办公软件领域占有绝对的主导地位,几乎每个职场人士都必须掌握Wor ...

  8. java实现支付宝接口--文档..转载

    //实现java支付宝很简单,只要从支付宝官方下载   http://help.alipay.com/support/index_sh.htm下载程序,配置一下参数就OK了:   1.先到http:/ ...

  9. iOS开发主要参考文档(转载)

    Objective-C,语言的系统详细资料.这是做iOS开发的前题与基础.https://developer.apple.com/library/ios/#documentation/Cocoa/Co ...

随机推荐

  1. 经典C语言编程注意点

    C/C++程序员应聘试题剖析 分中的2分.读者可从本文看到strcpy函数从2分到10分解答的例子,看看自己属于什么样的层次.此外,还有一些面试题考查面试者敏捷的思维能力. 分析这些面试题,本身包含很 ...

  2. PatentTips - Method for network interface sharing among multiple virtual machines

    BACKGROUND Many computing systems include a network interface card (NIC) to provide for communicatio ...

  3. Unity 3D本地公布WebPlayer版时&quot;Failed to download data file&quot;解决方式

    watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbGlzZW55YW5n/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA ...

  4. d堆

    就是d叉堆,是二叉堆的简单推广(http://blog.csdn.net/buleriver/article/details/38469907) 对于一个d堆.也是能够使用数组表示.关键是怎样通过索引 ...

  5. 与Greenplum度过的三个星期

    5月4日-5月24日.断断续续折腾了三个星期的Greenplum,总算告一段落了:扩容,发现扩不成容.仅仅好升级.升级,发现一堆错误,仅仅好暂停修复数据库:修好了,继续升级.升完级,发现错误.修啊修啊 ...

  6. uva_11997,K Smallest Sums优先队列

    #include<iostream> #include<cstdio> #include<cstring> #include<queue> #inclu ...

  7. grpc编译错误解决

    berli@berli-VirtualBox:~/grpc$ make [MAKE]    Generating cache.mk [C]       Compiling src/core/lib/s ...

  8. 【转】android新组件RecyclerView使用介绍和进阶使用,替用Gallery

    简介: RecyclerView是support-v7包中的新组件,是一个强大的滑动组件,与经典的ListView相比,同样拥有item回收复用的功能,但是直接把viewholder的实现封装起来,用 ...

  9. Webfont 的兼容性问题[持续更新]

    低版安卓手机的 webview 显示不了,另外黑莓手机显示出来是这样: 生成工具: 离线字体生成工具:webfont 在线字体生成平台:icomoon.io, iconfont.cn均有问题 其他一些 ...

  10. Spring mvc 启动 和 请求分发

    Spring mvc 启动 和 请求分发 启动加载: abstract class HttpServletBean extends HttpServlet void init() initServle ...