Skip to content

Commit f0b35bb

Browse files
committed
Document the reason for using RegisterNatives.
1 parent c0c80ce commit f0b35bb

File tree

1 file changed

+39
-0
lines changed

1 file changed

+39
-0
lines changed

README.md

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,45 @@ typical applications that need to use some C++ via JNI. The "Game Activity"
4343
template is a good starting point for game-like apps (that is, apps that do not
4444
use the Android UI, but instead render their own UI using OpenGL or Vulkan).
4545

46+
## Best practices shown here
47+
48+
There are a few best practices shown throughout this repository that should be
49+
explained, but there's no central place to discuss those in the code, so we'll
50+
discuss those here.
51+
52+
### `RegisterNatives`
53+
54+
We prefer using `RegisterNatives` via `JNI_OnLoad` over the name-based matching
55+
that Studio's New Project Wizard will typically create, e.g. JNI functions that
56+
follow the pattern `JNIEXPORT void JNICALL Java_com_etc_ClassName_methodName`.
57+
That approach to matching C/C++ functions to their Java `native` function (or
58+
Kotlin `external fun`) makes for a shorter demo when there are only a small
59+
number of functions, but it has a number of disadvantages:
60+
61+
1. Mistakes are uncovered late. An incorrectly named function will not cause an
62+
error until called by Java, so it's easier to ship bugs if your testing does
63+
not cover all JNI methods.
64+
2. All JNI symbols must be exported, leading to more relocations, larger
65+
binaries, and less effective link-time optimization (LTO).
66+
3. The first call to a JNI function will be slower than subsequent calls, as the
67+
Java call will first need to find a matching implementation.
68+
4. If you want to rename the function in Java, you have to also rename the C/C++
69+
function.
70+
71+
Instead, most apps should use `RegisterNatives` via `JNI_OnLoad`. This performs
72+
up-front registration of native methods with an explicit mapping. It takes a
73+
little bit more up-front-work, but doing so counters all of the disadvantages
74+
above:
75+
76+
1. Mistakes are caught early. An incorrectly named function will cause an error
77+
during library load.
78+
2. The only symbol that typically must be exported is `JNI_OnLoad`. Some use
79+
cases may additionally need `ANativeActivty_OnCreate` or similar.
80+
3. No lookup required for the first call to each native function, so performance
81+
overhead is consistent.
82+
4. The Java or C/C++ functions can be renamed at will, and only the map needs to
83+
be updated to match.
84+
4685
## Additional documentation
4786

4887
- [Add Native Code to Your Project](https://developer.android.com/studio/projects/add-native-code.html)

0 commit comments

Comments
 (0)