Mẫu: hello-jni

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 ".");