Lời khuyên cho nhà cung cấp phần mềm trung gian

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.

Việc phân phối phần mềm trung gian được xây dựng bằng NDK làm nảy sinh thêm một số vấn đề mà nhà phát triển ứng dụng không cần lo ngại. Thư viện tạo sẵn áp dụng một số lựa chọn triển khai cho người dùng.

Chọn cấp độ API và phiên bản NDK

Người dùng của bạn không thể sử dụng phiên bản minSdkVersion thấp hơn của bạn. Nếu ứng dụng của người dùng cần chạy trên API 21, bạn không thể xây dựng cho API 24. Bạn có thể xây dựng thư viện cho cấp độ API thấp hơn so với người dùng. Bạn có thể xây dựng cho API 16 mà vẫn tương thích với người dùng API 21.

Các phiên bản NDK phần lớn tương thích với nhau, nhưng đôi khi sẽ có những thay đổi phá vỡ khả năng tương thích. Nếu biết rằng tất cả người dùng đều sử dụng cùng một phiên bản NDK, tốt nhất bạn nên sử dụng phiên bản giống như của họ. Nếu không, hãy sử dụng phiên bản mới nhất.

Sử dụng STL

Nếu bạn đang viết mã C++ và sử dụng STL, việc bạn lựa chọn giữa libc++_sharedlibc++_static sẽ ảnh hưởng đến người dùng của bạn nếu bạn phân phối một thư viện dùng chung. Nếu phân phối thư viện dùng chung, bạn phải sử dụng libc++_shared hoặc đảm bảo rằng thư viện của bạn không hiển thị các ký hiệu của libc++. Cách tốt nhất để làm điều này là khai báo rõ ràng nền tảng ABI của bạn bằng tập lệnh phiên bản (cách này cũng giúp đảm bảo sự riêng tư cho thông tin triển khai của bạn). Ví dụ: Một thư viện số học đơn giản có thể có tập lệnh phiên bản sau:

LIBMYMATH {
global:
    add;
    sub;
    mul;
    div;
    # C++ symbols in an extern block will be mangled automatically. See
    # https://stackoverflow.com/a/21845178/632035 for more examples.
    extern "C++" {
        "pow(int, int)";
    }
local:
    *;
};

Tập lệnh phiên bản nên là tuỳ chọn ưu tiên vì đây là cách hiệu quả nhất để kiểm soát khả năng hiển thị ký hiệu. Đây là phương pháp hay nhất cho tất cả thư viện dùng chung, dù là phần mềm trung gian hay không, vì phương pháp này giúp thông tin triển khai của bạn không bị lộ và cải thiện thời gian tải.

Một tuỳ chọn khác kém hiệu quả hơn là sử dụng -Wl,--exclude-libs,libc++_static.a -Wl,--exclude-libs,libc++abi.a khi liên kết. Cách này kém hiệu quả hơn vì sẽ chỉ ẩn các ký hiệu trong thư viện được đặt tên rõ ràng và không có thông tin chẩn đoán nào được báo cáo đối với các thư viện không được sử dụng (lỗi chính tả trong tên thư viện không phải là lỗi và người dùng sẽ chịu trách nhiệm cập nhật danh sách thư viện). Phương pháp này cũng không ẩn thông tin triển khai của riêng bạn.

Phân phối thư viện gốc trong AAR

Trình bổ trợ Android cho Gradle có thể nhập các phần phụ thuộc gốc được phân phối trong AAR. Nếu người dùng của bạn đang sử dụng trình bổ trợ Android cho Gradle, thì đây sẽ là cách dễ nhất để họ sử dụng thư viện của bạn.

Thư viện gốc có thể được đóng gói vào AAR bằng AGP. Đây sẽ là tuỳ chọn dễ nhất nếu thư viện của bạn đã được tạo bằng externalnativeBuild.

Các bản dựng không phải của AGP có thể sử dụng ndkports hoặc thực hiện đóng gói theo cách thủ công bằng cách làm theo tài liệu về Prefab để tạo thư mục con prefab/ của AAR.

Phần mềm trung gian Java có thư viện JNI

Các thư viện Java bao gồm thư viện JNI (nói cách khác, AAR chứa jniLibs) cần cẩn thận sao cho thư viện JNI có trong đó sẽ không xung đột với các thư viện khác trong ứng dụng của người dùng. Ví dụ: Nếu AAR có libc++_shared.so, nhưng phiên bản libc++_shared.so khác với phiên bản ứng dụng đang dùng, sẽ chỉ có một phiên bản được cài đặt cho APK và điều đó có thể dẫn đến hành vi không đáng tin cậy.

Giải pháp đáng tin cậy nhất là các thư viện Java không nên thêm quá một thư viện JNI (đây cũng là lời khuyên hữu ích đối với các ứng dụng). Tất cả phần phụ thuộc bao gồm cả STL phải được liên kết tĩnh với thư viện triển khai và nên dùng một tập lệnh phiên bản để thực thi nền tảng ABI. Ví dụ: Thư viện Java com.example.foo có thư viện JNI libfooimpl.so nên sử dụng tập lệnh phiên bản sau:

LIBFOOIMPL {
global:
    JNI_OnLoad;
local:
    *;
};

Ví dụ này sử dụng registerNatives qua JNI_OnLoad như mô tả trong Các mẹo về JNI để đảm bảo rằng nền tảng ABI tối thiểu được hiển thị và thời gian tải thư viện sẽ được giảm thiểu.