Thêm mã C và C++ vào dự án của bạn

Thêm mã C và C++ vào dự án Android bằng cách đặt mã vào thư mục cpp trong mô-đun dự án. Khi bạn xây dựng dự án, mã này được biên dịch thành một thư viện gốc mà Gradle có thể đóng gói bằng ứng dụng của bạn. Sau đó, mã Java hoặc Kotlin có thể gọi các hàm trong thư viện gốc của bạn thông qua Giao diện gốc Java (JNI). Để tìm hiểu thêm về cách sử dụng khung JNI, hãy đọc các mẹo của JNI dành cho Android.

Android Studio hỗ trợ CMake – công cụ hữu ích cho các dự án nhiều nền tảng. Android Studio cũng hỗ trợ ndk-build – có thể nhanh hơn CMake nhưng chỉ hỗ trợ Android. Chúng tôi hiện không hỗ trợ sử dụng cả CMake và ndk-build trong cùng một mô-đun.

Để nhập một thư viện ndk-build hiện có vào dự án Android Studio của bạn, hãy tìm hiểu cách liên kết Gradle với dự án thư viện gốc của bạn.

Trang này cho bạn biết cách thiết lập Android Studio bằng các công cụ bản dựng cần thiết, tạo một dự án mới có hỗ trợ C/C++, và thêm tệp C/C++ mới vào dự án của bạn.

Thay vào đó, nếu bạn muốn thêm mã gốc vào một dự án hiện có, hãy làm theo các bước sau:

  1. Tạo các tệp mã nguồn gốc mới và thêm các tệp đó vào dự án Android Studio.
    • Hãy bỏ qua bước này nếu bạn đã có mã gốc hoặc muốn nhập một thư viện gốc được tạo sẵn.
  2. Định cấu hình CMake để tích hợp mã nguồn gốc của bạn vào thư viện. Nếu nhập và liên kết với các thư viện nền tảng hoặc tạo sẵn, bạn bắt buộc phải dùng tập lệnh bản dựng này.
    • Hãy bỏ qua bước này nếu bạn hiện có sẵn một thư viện gốc đã có tập lệnh bản dựng CMakeLists.txt hoặc sử dụng ndk-build đồng thời bao gồm một tập lệnh bản dựng Android.mk.
  3. Định cấu hình Gradle bằng cách cung cấp một đường dẫn cho tệp tập lệnh CMake hoặc ndk-build. Gradle sẽ sử dụng tập lệnh bản dựng để nhập mã nguồn vào dự án Android Studio và đóng gói thư viện gốc vào ứng dụng.

Sau khi định cấu hình dự án, bạn có thể truy cập vào các hàm gốc từ mã Java hoặc Kotlin bằng khung JNI. Để tạo bản dựng và chạy ứng dụng, bạn chỉ cần nhấp vào Chạy Tạo bản dựng rồi chạy ứng dụng từ thanh trình đơn.

Lưu ý: Nếu dự án của bạn hiện sử dụng công cụ ndkCompile (không còn được dùng nữa), hãy chuyển sang dùng CMake hoặc ndk-build.

Tải NDK và các công cụ bản dựng xuống

Để biên dịch và gỡ lỗi mã gốc cho ứng dụng, bạn cần có các thành phần sau:

  • Android Native Development Kit (NDK): một bộ công cụ cho phép bạn sử dụng mã C và C++ với Android. NDK cung cấp các thư viện nền tảng cho phép bạn quản lý các hoạt động gốc và truy cập vào các thành phần của thiết bị thực tế, chẳng hạn như cảm biến và thiết bị nhập bằng cách nhấn.
  • CMake: một công cụ bản dựng bên ngoài hoạt động cùng Gradle để xây dựng thư viện gốc. Nếu bạn chỉ định sử dụng ndk-build thì không cần đến thành phần này.
  • LLDB: Trình gỡ lỗi trong Android Studio dùng để gỡ lỗi mã gốc.

Để biết thông tin về cách cài đặt các thành phần này, hãy xem Cài đặt và định cấu hình NDK và CMake.

Tạo dự án mới có hỗ trợ C/C++

Quy trình tạo một dự án mới có hỗ trợ mã gốc tương tự như quy trình tạo mọi dự án Android Studio khác, nhưng có thêm một bước sau:

  1. Trong mục Chọn dự án của bạn (Choose your project) trong trình hướng dẫn, hãy chọn loại dự án C++ gốc.
  2. Nhấp vào Tiếp theo.
  3. Hoàn thành tất cả các trường khác trong phần tiếp theo của trình hướng dẫn.
  4. Nhấp vào Tiếp theo.
  5. Trong mục Tuỳ chỉnh Hỗ trợ C++ của trình hướng dẫn, bạn có thể tuỳ chỉnh dự án của mình với trường Tiêu chuẩn C++.
    • Sử dụng danh sách thả xuống để chọn quy trình chuẩn hoá C++ mà bạn muốn sử dụng. Chọn Chế độ mặc định cho Chuỗi công cụ (Toolchain Default) đồng nghĩa với việc sử dụng chế độ cài đặt CMake mặc định.
  6. Nhấp vào Hoàn tất (Finish).

Sau khi Android Studio hoàn tất quá trình tạo dự án mới, hãy mở ngăn Dự án (Project) ở phía bên trái của IDE và chọn chế độ xem Android từ trình đơn. Android Studio sẽ thêm nhóm cpp như minh hoạ trong hình 1:

Hình 1. Nhóm chế độ xem Android cho mã nguồn gốc và tập lệnh bản dựng bên ngoài.

Lưu ý: Chế độ xem này không phản ánh hệ phân cấp tệp thực tế trên ổ đĩa, mà nhóm các tệp tương tự nhau để tinh giản quá trình điều hướng trong dự án của bạn.

Nhóm cpp là nơi bạn có thể tìm thấy tất cả các tệp mã nguồn gốc, tiêu đề, tập lệnh bản dựng cho CMake hoặc ndk-build, và các thư viện có sẵn nằm trong dự án của bạn. Đối với các dự án mới, Android Studio sẽ tạo một tệp nguồn C++ mẫu, native-lib.cpp và đặt tệp đó vào thư mục src/main/cpp/ của mô-đun ứng dụng. Mã nguồn mẫu này cung cấp một hàm C++ đơn giản, stringFromJNI(), hàm này trả về chuỗi "Hello from C++". Hãy tìm hiểu cách thêm tệp nguồn bổ sung vào dự án trong phần hướng dẫn cách tạo tệp nguồn gốc mới.

Tương tự như cách các tệp build.gradle hướng dẫn Gradle cách tạo bản dựng ứng dụng, CMake và ndk-build yêu cầu một tập lệnh bản dựng để biết cách xây dựng thư viện gốc. Đối với các dự án mới, Android Studio sẽ tạo một tập lệnh bản dựng cho CMake, CMakeLists.txt và đặt tập lệnh này vào thư mục gốc của mô-đun. Để tìm hiểu thêm về nội dung của tập lệnh bản dựng này, hãy đọc phần Định cấu hình CMake.

Xây dựng và chạy ứng dụng mẫu

Khi bạn nhấp vào Chạy Tạo bản dựng rồi chạy ứng dụng từ thanh trình đơn, Android Studio sẽ tạo bản dựng và chạy một ứng dụng hiển thị văn bản "Lời chào từ C++" trên thiết bị hoặc trình mô phỏng Android của bạn. Phần tổng quan sau đây mô tả các sự kiện xảy ra khi tạo bản dựng và chạy ứng dụng mẫu:

  1. Gradle yêu cầu tập lệnh bản dựng ngoài, CMakeLists.txt.
  2. CMake thực hiện các lệnh trong tập lệnh bản dựng để biên dịch tệp nguồn C++, native-lib.cpp, thành một thư viện đối tượng dùng chung và đặt tên cho tệp này là libnative-lib.so, sau đó Gradle sẽ gói tệp này vào trong ứng dụng.
  3. Trong thời gian chạy, MainActivity của ứng dụng sẽ tải thư viện gốc bằng cách sử dụng System.loadLibrary(). Hàm gốc của thư viện, stringFromJNI(), hiện đã có trong ứng dụng.
  4. MainActivity.onCreate() gọi stringFromJNI(), trả về "Hello from C++" và sử dụng hàm này để cập nhật TextView.

Để xác minh rằng Gradle đã đóng gói thư viện gốc trong ứng dụng, hãy sử dụng Công cụ phân tích APK:

  1. Chọn Xây dựng > Xây dựng gói/tệp APK > Xây dựng tệp APK (Build > Build Bundles(s) / APK(s) > Build APK(s)).
  2. Chọn Xây dựng > Phân tích APK (Build > Analyze APK).
  3. Chọn APK hoặc AAB từ thư mục app/build/outputs/ và nhấp vào OK.
  4. Như minh hoạ trong hình 2, bạn có thể thấy libnative-lib.so trong cửa sổ Công cụ phân tích APK trong lib/<ABI>/.

    Hình 2. Xác định thư viện gốc bằng Công cụ phân tích APK.

Mẹo: Nếu bạn muốn thử nghiệm với các ứng dụng Android khác có sử dụng mã gốc, hãy nhấp vào Tệp > Mới > Nhập mẫu (File > New > Import Sample) rồi chọn một dự án mẫu từ Danh sách Ndk.

Tạo tệp nguồn C/C++ mới

Để thêm tệp nguồn C/C++ mới vào dự án hiện có, hãy tiến hành như sau:

  1. Nếu bạn chưa có thư mục cpp/ trong nhóm tài nguyên chính của ứng dụng, hãy tạo một thư mục như sau:
    1. Mở ngăn Dự án (Project) ở bên trái của IDE và chọn chế độ xem Dự án (Project) từ trình đơn.
    2. Chuyển đến your-module > src.
    3. Nhấp chuột phải vào thư mục main rồi chọn Mới > Thư mục (New > Directory).
    4. Nhập cpp làm tên thư mục và nhấp vào OK.

  2. Nhấp chuột phải vào thư mục cpp/ rồi chọn Mới > Tệp nguồn C/C++ (New > C/C++ Source File).
  3. Nhập tên cho tệp nguồn, chẳng hạn như native-lib.
  4. Từ trình đơn Loại (Type), hãy chọn loại đuôi tệp cho tệp nguồn, chẳng hạn như .cpp.
    • Nhấp vào Chỉnh sửa loại tệp (Edit File Types) để thêm các loại tệp khác vào trình đơn, chẳng hạn như .cxx hoặc .hxx. Trong hộp thoại Đuôi tệp mới (New File Extensions) bật lên, hãy chọn một đuôi tệp khác từ trình đơn Phần mở rộng nguồn (Source Extension) và Phần mở rộng tiêu đề (Header Extension) rồi nhấp vào OK.
  5. Để tạo tệp tiêu đề, hãy chọn hộp đánh dấu Tạo tiêu đề liên kết (Create an associated header).
  6. Nhấp vào OK.

Sau khi thêm các tệp C/C++ mới vào dự án, bạn vẫn cần định cấu hình CMake để đưa các tệp này vào thư viện gốc.

Tài nguyên khác

Để tìm hiểu thêm về cách hỗ trợ mã C/C++ trong ứng dụng của bạn, hãy thử dùng tài nguyên sau đây.

Lớp học lập trình

  • Tạo Hello-CMake với Android Studio Lớp học lập trình này hướng dẫn bạn cách sử dụng mẫu Android Studio CMake để bắt đầu phát triển dự án Android NDK.