Skip to content

Commit 1ee099f

Browse files
committed
Document the reason for using RegisterNatives.
1 parent a8cd972 commit 1ee099f

File tree

1 file changed

+43
-0
lines changed

1 file changed

+43
-0
lines changed

README.md

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,49 @@ 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+
5. Android Studio cannot auto-fix typos in your native function names, although
71+
it can auto-generate new ones.
72+
73+
Instead, most apps should use `RegisterNatives` via `JNI_OnLoad`. This performs
74+
up-front registration of native methods with an explicit mapping. It takes a
75+
little bit more up-front-work, but doing so counters all of the disadvantages
76+
above:
77+
78+
1. Mistakes are caught early. An incorrectly named function will cause an error
79+
during library load.
80+
2. The only symbol that typically must be exported is `JNI_OnLoad`. Some use
81+
cases may additionally need `ANativeActivty_OnCreate` or similar.
82+
3. No lookup required for the first call to each native function, so performance
83+
overhead is consistent.
84+
4. The Java or C/C++ functions can be renamed at will, and only the map needs to
85+
be updated to match.
86+
5. Android Studio can warn you and auto-fix common mistakes in class names and
87+
function signatures.
88+
4689
## Additional documentation
4790

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

0 commit comments

Comments
 (0)