Mẫu: hello-jni
Sử dụng bộ sưu tập để sắp xếp ngăn nắp các trang
Lưu và phân loại nội dung dựa trên lựa chọn ưu tiên của bạn.
Mẫu này hướng dẫn toàn bộ về hello-jni, một ứng dụng C/C++ tối thiểu được tạo bằng NDK. Mẫu này nằm trong thư mục hello-jni của kho lưu trữ ndk-samples, bên trong nhánh android-mk.
Android.mk
Hai dòng sau đây cung cấp tên của tệp nguồn gốc, cùng với tên của thư viện dùng chung cần tạo. Tên đầy đủ của thư viện được tạo là libhello-jni.so, sau khi hệ thống xây dựng thêm tiền tố lib và đuôi .so.
LOCAL_SRC_FILES := hello-jni.c
LOCAL_MODULE := hello-jni
Để biết thêm thông tin về chức năng của tệp Android.mk và cách dùng tệp này, hãy xem bài viết Android.mk.
Application.mk
Dòng này cho hệ thống xây dựng biết cần dựa trên CPU và cấu trúc nào khi tạo. Trong ví dụ này, hệ thống xây dựng tạo cho tất cả cấu trúc được hỗ trợ.
APP_ABI := all
Để biết thêm thông tin về tệp Application.mk và cách sử dụng tệp đó, hãy xem bài viết Application.mk.
Triển khai phía Java
Tệp helloJNI.java nằm ở hellojni/src/com/example/hellojni/. Tệp này gọi một hàm để lấy một chuỗi từ phía gốc, sau đó hiển thị chuỗi đó trên màn hình.
Mã nguồn có ba dòng mà người dùng NDK nên đặc biệt chú ý.
Ba dòng này được trình bày ở đây theo thứ tự sử dụng, chứ không phải theo thứ tự dòng.
Lệnh gọi hàm này tải tệp .so khi khởi động ứng dụng.
Kotlin
System.loadLibrary("hello-jni")
Java
System.loadLibrary("hello-jni");
Từ khoá native trong nội dung khai báo của phương thức này cho máy ảo biết rằng hàm nằm trong thư viện dùng chung (nghĩa là được triển khai ở phía gốc).
Kotlin
external fun stringFromJNI(): String
Java
public native String stringFromJNI();
Khung Android gọi hàm được tải và khai báo trong các bước trước, hiển thị chuỗi trên màn hình.
Kotlin
tv.text = stringFromJNI()
Java
tv.setText( stringFromJNI() );
Triển khai phía C
Tệp hello-jni.c nằm ở hello-jni/jni/. Tệp này chứa một hàm trả về một chuỗi mà phía Java đã yêu cầu). Nội dung khai báo của hàm như sau:
JNIEXPORT jstring JNICALL
Java_com_example_hellojni_HelloJni_stringFromJNI( JNIEnv* env,
jobject thiz )
Nội dung khai báo này tương ứng với hàm gốc được khai báo trong mã nguồn Java. Loại dữ liệu trả về jstring là một loại dữ liệu được xác định trong Thông số kỹ thuật giao diện gốc Java. Thật ra đây không phải là một chuỗi, mà là con trỏ đến một chuỗi Java.
Sau jstring là tên hàm được dựa trên tên hàm Java và đường dẫn đến tệp chứa hàm đó. Tạo tên hàm theo các quy tắc sau:
- Thêm
Java_ vào trước tên hàm.
- Mô tả đường dẫn tệp tương ứng với thư mục nguồn cấp cao nhất.
- Sử dụng dấu gạch dưới thay cho dấu gạch chéo xuôi.
- Bỏ qua đuôi tệp
.java.
- Sau dấu gạch dưới cuối cùng, hãy thêm tên hàm.
Theo các quy tắc này, ví dụ sau sử dụng tên hàm Java_com_example_hellojni_HelloJni_stringFromJNI. Tên này chỉ một hàm Java có tên là stringFromJNI(), nằm trong hellojni/src/com/example/hellojni/HelloJni.java.
JNIEnv* là con trỏ tới máy ảo và jobject là con trỏ tới đối tượng this ngầm định được truyền từ phía Java.
Dòng sau gọi API máy ảo (*env) và truyền cho API này một giá trị trả về: nghĩa là chuỗi mà hàm bên phía Java đã yêu cầu.
return (*env)->NewStringUTF(env, "Hello from JNI !
Compiled with ABI " ABI ".");
Nội dung và mã mẫu trên trang này phải tuân thủ các giấy phép như mô tả trong phần Giấy phép nội dung. Java và OpenJDK là nhãn hiệu hoặc nhãn hiệu đã đăng ký của Oracle và/hoặc đơn vị liên kết của Oracle.
Cập nhật lần gần đây nhất: 2025-07-26 UTC.
[[["Dễ hiểu","easyToUnderstand","thumb-up"],["Giúp tôi giải quyết được vấn đề","solvedMyProblem","thumb-up"],["Khác","otherUp","thumb-up"]],[["Thiếu thông tin tôi cần","missingTheInformationINeed","thumb-down"],["Quá phức tạp/quá nhiều bước","tooComplicatedTooManySteps","thumb-down"],["Đã lỗi thời","outOfDate","thumb-down"],["Vấn đề về bản dịch","translationIssue","thumb-down"],["Vấn đề về mẫu/mã","samplesCodeIssue","thumb-down"],["Khác","otherDown","thumb-down"]],["Cập nhật lần gần đây nhất: 2025-07-26 UTC."],[],[],null,["# Sample: hello-jni\n\nThis sample guides you through hello-jni, a minimal\nC/C++ application built with the NDK. This sample is in the [hello-jni](https://github.com/android/ndk-samples/tree/android-mk/hello-jni) directory\nof ndk-samples repo, inside [android-mk branch](https://github.com/android/ndk-samples/tree/android-mk).\n\nAndroid.mk\n----------\n\nThe following two lines provide the name of the native source file, along\nwith the name of the shared library to build. The full name of the built\nlibrary is `libhello-jni.so`, once the build system adds the\n`lib` prefix and the `.so` extension. \n\n```\nLOCAL_SRC_FILES := hello-jni.c\nLOCAL_MODULE := hello-jni\n```\n\nFor more information about what the `Android.mk` file does, and how to use it, see\n[Android.mk](/ndk/guides/android_mk).\n\nApplication.mk\n--------------\n\nThis line tells the build system the CPU and architecture against which to build. In this\nexample, the build system builds for all supported architectures. \n\n```\nAPP_ABI := all\n```\n\nFor more information about the `Application.mk` file, and how to use it, see\n[Application.mk](/ndk/guides/application_mk).\n\nJava-side Implementation\n------------------------\n\nThe `helloJNI.java` file is located in `hellojni/src/com/example/hellojni/`. It calls\na function to retrieve a string from the native side, then displays it on the screen.\n\nThe source code contains three lines of particular interest to the NDK user.\nThey are presented here in the order in which they are used, rather than by\nline order.\n\nThis function call loads the `.so` file upon application startup. \n\n### Kotlin\n\n```kotlin\nSystem.loadLibrary(\"hello-jni\")\n```\n\n### Java\n\n```java\nSystem.loadLibrary(\"hello-jni\");\n```\n\nThe `native` keyword in this method declaration tells the\nvirtual machine that the function is in the shared library (that is, implemented on the native\nside). \n\n### Kotlin\n\n```kotlin\nexternal fun stringFromJNI(): String\n```\n\n### Java\n\n```java\npublic native String stringFromJNI();\n```\n\nThe Android framework calls the function loaded and declared in the\nprevious steps, displaying the string on the screen. \n\n### Kotlin\n\n```kotlin\ntv.text = stringFromJNI()\n```\n\n### Java\n\n```java\ntv.setText( stringFromJNI() );\n```\n\nC-side Implementation\n---------------------\n\nThe `hello-jni.c` file is located in `hello-jni/jni/`. It contains a function that\nreturns a string that [the Java side requested](#ji)). The function declaration is as\nfollows: \n\n```c++\nJNIEXPORT jstring JNICALL\nJava_com_example_hellojni_HelloJni_stringFromJNI( JNIEnv* env,\n jobject thiz )\n```\n\nThis declaration corresponds to the native function declared in the\nJava source code. The return type, `jstring`, is a data type defined\nin the\n[Java Native\nInterface Specification](http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/jniTOC.html). It is not actually a string, but a\npointer to a Java string.\n\nAfter `jstring` comes the function name, which is based on the\nJava function name and the path to the file containing it. Construct it\naccording to the following rules:\n\n- Prepend `Java_` to it.\n- Describe the filepath relative to the top-level source directory.\n- Use underscores in place of forward slashes.\n- Omit the `.java` file extension.\n- After the last underscore, append the function name.\n\nFollowing these rules, this example uses the function name\n`Java_com_example_hellojni_HelloJni_stringFromJNI`. This name refers to a Java\nfunction called `stringFromJNI()`, which resides in\n`hellojni/src/com/example/hellojni/HelloJni.java`.\n\n`JNIEnv*` is the pointer to the VM, and\n`jobject` is a pointer to the implicit `this` object passed from\nthe Java side.\n\nThe following line calls the VM API `(*env)`, and passes it a return value:\nthat is, the string that the function on the Java side had requested. \n\n```c++\nreturn (*env)-\u003eNewStringUTF(env, \"Hello from JNI !\nCompiled with ABI \" ABI \".\");\n```"]]