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

Android chromium 2的更多相关文章

  1. Android Chromium WebView学习启动篇

    Android从4.4起提供基于Chromium实现的WebView.此前WebView基于WebKit实现.WebKit提供网页解析.布局和绘制以及JS执行等基础功能.Chromium在WebKit ...

  2. Android chromium 1

    For Developers‎ > ‎Design Documents‎ > ‎ Java Resources on Android Overview Chrome for Android ...

  3. 35 Top Open Source Companies

    https://www.datamation.com/open-source/35-top-open-source-companies-1.html If you think of open sour ...

  4. DevTools 实现原理与性能分析实战

    一.引言 从 2008 年 Google 释放出第一版的 Chrome 后,整个 Web 开发领域仿佛被注入了一股新鲜血液,渐渐打破了 IE 一家独大的时代.Chrome 和 Firefox 是 W3 ...

  5. Ubuntu下编译Chromium for Android

    转自:http://blog.csdn.net/fsz521/article/details/18036835 下源码git clone https://chromium.googlesource.c ...

  6. 理解WebKit和Chromium: 调试Android系统上的Chromium

    转载请注明原文地址:http://blog.csdn.net/milado_nju 1. Android上的调试技术 在Android系统上,开发人员能够使用两种不同的语言来开发应用程序,一种是Jav ...

  7. chromium for android v34 2dcanvas硬件渲染实现分析

    这篇接着上一篇2dcanvas硬件绘制,分析保存绘制结果的texture被合成到on screen framebuffer上的过程. 1.webkit为canvas元素相应的render树节点Rend ...

  8. Chromium on Android: Android在系统Chromium为了实现主消息循环分析

    总结:刚开始接触一个Chromium on Android时间.很好奇Chromium主消息循环是如何整合Android应用. 为Android计划,一旦启动,主线程将具有Java消息层循环处理系统事 ...

  9. 理解WebKit和Chromium: Android 4.4 上的Chromium WebView

    转载请注明原文地址:http://blog.csdn.net/milado_nju ## 概述 相信读者已经注意到了,在最新的Android 4.4 Kitkat版本中,原本基于Android Web ...

随机推荐

  1. Windbg调试托管代码

    Windbg调试.net托管代码需要借助于SOS.dll,.Net 4.0的32位sos.dll的路径在C:\Windows\Microsoft.NET\Framework\v4.0.30319,64 ...

  2. SpringBoot(一) 基础入门

    SpringBoot简要 简化Spring应用开发的一个框架: 整个Spring技术栈的一个大整合: J2EE开发的一站式解决方案: 自动配置:针对很多Spring应用程序常见的应用功能,Spring ...

  3. jdk1.8源码分析-hashMap

    在Java语言中使用的最多的数据结构大概右两种,第一种是数组,比如Array,ArrayList,第二种链表,比如ArrayLinkedList,基于数组的数据结构特点是查找速度很快,时间复杂度为 O ...

  4. PKI和加密,散列算法

    Day 11-PKI和加密,散列算法 PKI(Public Key Infrastructure公钥基础设施) 1 PKI(Public Key Infrastructure公钥基础设施)回顾学习 - ...

  5. sass的用法小结(一)

    1. 使用变量; sass让人们受益的一个重要特性就是它为css引入了变量.你可以把反复使用的css属性值 定义成变量,然后通过变量名来引用它们,而无需重复书写这一属性值.或者,对于仅使用过一 次的属 ...

  6. Vue学习之v-if与v-show的区别

    v-if和v-show具有类似的功能,不过v-if才是真正的条件渲染,他会根据表达式适当的销毁或重建元素及绑定事件或子组件.若表达式初始值为false,则一开始元素或组件不会渲染,只有当第一次为真时, ...

  7. 洛谷 P1403 [AHOI2005]约数研究

    怎么会有这么水的省选题 一定是个签到题. 好歹它也是个省选题,独立做出要纪念一下 很容易发现在1~n中,i的因子数是n / i 那就枚举每一个i然后加起来就OK了 #include<cstdio ...

  8. P1064 金明的预算方案 (依赖性背包问题)

    这道题可以用分组背包来做. 但是分组有两种方式 一种是把主件,主件+附件1,主件+附件2分成一组 组内只能选一个物品 一种是建一颗树,用树形dp的方式去做 第二种更通用,就算物品的依赖关系是森林都可以 ...

  9. pandas学习笔记 - 文件的写入和输出

    # -*- coding: utf-8 -*- """ Created on Tue Aug 28 22:19:26 2018   @author: Dev " ...

  10. 【转载】Failed to load class "org.slf4j.impl.StaticLoggerBinder".问题解决

    在进行hibernate配置好后运行测试类的时候出现: SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder" ...