Tạo một thư viện Android

Thư viện Android có cấu trúc giống như một mô-đun ứng dụng Android. Trong thư viện này có mọi thứ cần thiết để tạo ứng dụng, bao gồm cả mã nguồn, tệp tài nguyên và tệp kê khai của Android.

Tuy nhiên, thay vì biên dịch thành một APK chạy trên thiết bị, thì thư viện Android sẽ biên dịch thành tệp Android Archive (AAR) mà bạn có thể dùng làm phần phụ thuộc cho mô-đun ứng dụng Android. Không giống như tệp JAR, tệp AAR cung cấp chức năng sau đây cho các ứng dụng Android:

  • Các tệp AAR có thể chứa các tài nguyên Android và một tệp kê khai, cho phép bạn gói các tài nguyên được chia sẻ như bố cục và các đối tượng có thể vẽ bên cạnh các lớp và phương thức trong Kotlin hoặc Java.
  • Tệp AAR có thể chứa thư viện C/C++ để cho mã C/C++ của mô-đun ứng dụng dùng.

Mô-đun thư viện hữu ích trong các trường hợp sau:

  • Khi tạo nhiều ứng dụng dùng một số thành phần giống nhau, chẳng hạn như hoạt động, dịch vụ hoặc bố cục của giao diện người dùng
  • Khi tạo một ứng dụng tồn tại ở nhiều biến thể APK, chẳng hạn như một phiên bản miễn phí và một phiên bản trả phí, dùng chung các thành phần cốt lõi

Trong từng trường hợp, hãy di chuyển các tệp mà bạn muốn sử dụng lại vào mô-đun thư viện, sau đó thêm thư viện làm phần phụ thuộc cho mỗi mô-đun ứng dụng.

Trang này giải thích cách tạo và sử dụng mô-đun thư viện Android. Để biết hướng dẫn về cách phát hành thư viện, hãy xem bài viết Phát hành thư viện

Tạo mô-đun thư viện

Để tạo một mô-đun thư viện mới trong dự án của bạn, hãy tiến hành như sau:

  1. Nhấp vào File > New > New Module (Tệp > Mới > Mô-đun mới).
  2. Trong hộp thoại Create New Module (Tạo mô-đun mới) xuất hiện, hãy nhấp vào Android Library (Thư viện Android) rồi nhấp vào Next (Tiếp theo).

    Ngoài ra, bạn cũng có thể tạo thư viện Kotlin hoặc Java để tạo tệp JAR truyền thống. Tuy hữu ích cho nhiều dự án (đặc biệt là khi bạn muốn chia sẻ mã với các nền tảng khác), nhưng tệp JAR lại không cho phép bạn thêm tài nguyên Android hoặc tệp kê khai hữu ích cho việc sử dụng lại mã trong các dự án Android. Hướng dẫn này tập trung vào quy trình tạo thư viện Android.

  3. Đặt tên cho thư viện và chọn một phiên bản SDK tối thiểu cho mã trong thư viện, rồi nhấp vào Finish (Hoàn tất).

Sau khi quá trình đồng bộ hoá dự án Gradle hoàn tất, mô-đun thư viện sẽ xuất hiện trong ngăn Project (Dự án). Nếu bạn không thấy thư mục mô-đun mới, hãy đảm bảo ngăn đang hiển thị khung hiển thị Android.

Chuyển đổi mô-đun ứng dụng thành mô-đun thư viện

Nếu đang có một mô-đun ứng dụng chứa mã mà bạn muốn sử dụng lại, bạn có thể chuyển mô-đun đó thành một mô-đun thư viện như sau:

  1. Mở tệp build.gradle ở cấp mô-đun (nếu bạn đang sử dụng Groovy) hoặc tệp build.gradle.kts (nếu bạn đang sử dụng tập lệnh Kotlin).
  2. Xoá dòng cho applicationId. Chỉ một mô-đun ứng dụng Android mới có thể xác định điều này.
  3. Tìm khối `plugins` (trình bổ trợ) ở đầu tệp có dạng như sau:

    Groovy

      plugins {
          id 'com.android.application'
      }
      

    Kotlin

      plugins {
          id("com.android.application")
      }
      

    Hãy thay đổi thành như sau:

    Groovy

      plugins {
          id 'com.android.library'
      }
      

    Kotlin

      plugins {
          id("com.android.library")
      }
      
  4. Lưu tệp và nhấp vào File > Sync Project with Gradle Files (Tệp > Đồng bộ hoá dự án với các tệp Gradle).

Cấu trúc của mô-đun vẫn giữ nguyên, nhưng hiện tại hoạt động như một thư viện Android. Bản dựng này sẽ tạo một tệp AAR thay vì APK.

Khi bạn muốn xây dựng tệp AAR, hãy chọn mô-đun thư viện trong cửa sổ Project (Dự án) rồi nhấp vào Build > Build APK (Xây dựng > Xây dựng APK).

Thêm phần phụ thuộc bằng hộp thoại Project Structure (Cấu trúc dự án)

Bạn có thể sử dụng hộp thoại Project Structure (Cấu trúc dự án) để thêm các phần phụ thuộc vào dự án. Các phần sau đây mô tả cách sử dụng hộp thoại để thêm phần phụ thuộc.

Sử dụng thư viện của bạn từ cùng một dự án

Để dùng mã của thư viện Android mới trong một ứng dụng hoặc mô-đun thư viện khác trong cùng một dự án, hãy thêm phần phụ thuộc cấp dự án:

  1. Chuyển đến File > Project Structure > Dependencies (Tệp > Cấu trúc dự án > Phần phụ thuộc).
  2. Chọn mô-đun mà bạn muốn thêm thư viện.
  3. Trong thẻ Declared Dependencies (Phần phụ thuộc đã khai báo), hãy nhấp vào biểu tượng rồi chọn Module Dependency (Phần phụ thuộc của mô-đun) trên trình đơn.

  4. Trong hộp thoại Add Module Dependency (Thêm phần phụ thuộc của mô-đun), hãy chọn mô-đun thư viện của bạn.

    Hộp thoại Add module dependency (Thêm phần phụ thuộc của mô-đun) trong phần Project Structure (Cấu trúc dự án)

  5. Chọn cấu hình yêu cầu phần phụ thuộc này hoặc chọn implementation (triển khai) nếu phần phụ thuộc đó áp dụng cho mọi cấu hình, rồi nhấp vào OK.

Android Studio chỉnh sửa tệp build.gradle hoặc build.gradle.kts của mô-đun để thêm phần phụ thuộc, có dạng như sau:

Groovy

  implementation project(path: ":example-library")

Kotlin

  implementation(project(":example-library"))

Sử dụng thư viện của bạn trong các dự án khác

Bạn nên chia sẻ các phần phụ thuộc (JAR và AAR) với một kho lưu trữ Maven, được lưu trữ trên một dịch vụ như Maven Central hoặc với cấu trúc thư mục trên ổ đĩa cục bộ của bạn. Để biết thêm thông tin về cách sử dụng kho lưu trữ Maven, hãy xem phần Kho lưu trữ từ xa.

Khi bạn phát hành một thư viện Android lên một kho lưu trữ Maven, siêu dữ liệu sẽ được đưa vào để các phần phụ thuộc của thư viện có trong bản dựng đang dùng. Điều này giúp thư viện có thể tự động loại bỏ trùng lặp nếu thư viện đó được dùng ở nhiều nơi.

Để dùng mã của thư viện Android cho một mô-đun ứng dụng khác trong một dự án khác, hãy làm như sau:

  1. Chuyển đến File > Project Structure > Dependencies (Tệp > Cấu trúc dự án > Phần phụ thuộc).
  2. Trong thẻ Declared Dependencies (Phần phụ thuộc đã khai báo), hãy nhấp vào biểu tượng rồi chọn Library Dependency (Phần phụ thuộc thư viện) trên trình đơn.

  3. Trong hộp thoại Add Library Dependency (Thêm phần phụ thuộc của thư viện), hãy dùng hộp tìm kiếm để tìm thư viện mà bạn muốn thêm. Biểu mẫu này tìm kiếm những kho lưu trữ được chỉ định trong khối dependencyResolutionManagement { repositories {...}} thuộc tệp settings.gradle hoặc settings.gradle.kts.

    Hộp thoại Add library dependency (Thêm phần phụ thuộc của thư viện) trong phần Project Structure (Cấu trúc dự án)

  4. Chọn cấu hình yêu cầu phần phụ thuộc này hoặc chọn implementation (triển khai) nếu phần phụ thuộc đó áp dụng cho mọi cấu hình, rồi nhấp vào OK.

Kiểm tra tệp build.gradle hoặc build.gradle.kts của ứng dụng để xác nhận rằng một nội dung khai báo tương tự như sau sẽ xuất hiện (tuỳ thuộc vào cấu hình bản dựng bạn chọn):

Groovy

  implementation 'com.example:examplelibrary:1.0.0'

Kotlin

  implementation("com.example:examplelibrary:1.0.0")

Thêm AAR hoặc JAR làm phần phụ thuộc

Để dùng mã của thư viện Android trong một mô-đun ứng dụng khác, hãy tiến hành như sau:

  1. Chuyển đến File > Project Structure > Dependencies (Tệp > Cấu trúc dự án > Phần phụ thuộc).
  2. Trong thẻ Declared Dependencies (Phần phụ thuộc đã khai báo), hãy nhấp vào biểu tượng rồi chọn Jar Dependency (Phần phụ thuộc Jar) trên trình đơn.

  3. Trong hộp thoại Add Jar/Aar Dependency (Thêm phần phụ thuộc Jar/Aar), hãy nhập đường dẫn đến tệp AAR hoặc JAR rồi chọn cấu hình mà phần phụ thuộc này sẽ áp dụng. Nếu thư viện đã được cung cấp cho tất cả các cấu hình, hãy chọn cấu hình implementation (triển khai).

    Hộp thoại Add AAR dependency (Thêm phần phụ thuộc của AAR) trong phần Project Structure (Cấu trúc dự án)

    Kiểm tra tệp build.gradle hoặc build.gradle.kts của ứng dụng để xác nhận rằng một nội dung khai báo tương tự như sau sẽ xuất hiện (tuỳ thuộc vào cấu hình bản dựng bạn chọn):

    Groovy

      implementation files('my_path/my_lib.aar')

    Kotlin

      implementation(files("my_path/my_lib.aar"))

Để nhập một phần phụ thuộc trên bản dựng Gradle chạy bên ngoài Android Studio, hãy thêm một đường dẫn đến phần phụ thuộc đó trong tệp build.gradle hoặc build.gradle.kts của ứng dụng. Ví dụ:

Groovy

dependencies {
    implementation fileTree(dir: "libs", include: ["*.jar", "*.aar"])
}

Kotlin

dependencies {
    implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar", "*.aar"))))
}

Để biết thêm về cách thêm các phần phụ thuộc Gradle, hãy xem bài viết Thêm các phần phụ thuộc cho bản dựng.

Khai báo tài nguyên công khai

Tài nguyên bao gồm tất cả các tệp trong thư mục res/ của dự án, chẳng hạn như hình ảnh. Theo mặc định, mọi tài nguyên trong thư viện đều ở chế độ công khai. Để đặt tất cả các tài nguyên ở chế độ riêng tư ngầm, bạn phải xác định ít nhất một thuộc tính cụ thể là công khai.

Để khai báo tài nguyên công khai, hãy thêm nội dung khai báo <public> vào tệp public.xml của thư viện. Nếu trước đó chưa từng thêm tài nguyên công khai, thì bạn cần tạo tệp public.xml trong thư mục res/values/ của thư viện.

Mã ví dụ sau đây sẽ tạo 2 tài nguyên chuỗi công khai có tên là mylib_app_namemylib_public_string:

<resources>
    <public name="mylib_app_name" type="string"/>
    <public name="mylib_public_string" type="string"/>
</resources>

Để ngăn người dùng thư viện của bạn truy cập vào các tài nguyên chỉ dùng nội bộ, hãy sử dụng cơ chế chỉ định riêng tư, tự động này bằng cách khai báo một hoặc nhiều tài nguyên công khai. Ngoài ra, bạn có thể đặt tất cả các tài nguyên ở chế độ riêng tư bằng cách thêm thẻ <public /> trống. Thao tác này không đánh dấu nội dung nào là công khai và đặt tất cả tài nguyên ở chế độ riêng tư.

Mọi tài nguyên mà bạn vẫn muốn các nhà phát triển sử dụng thư viện của bạn nhìn thấy đều phải hiển thị công khai.

Việc ngầm đặt các thuộc tính ở chế độ riêng tư sẽ ngăn người dùng thư viện của bạn nhận nội dung đề xuất hoàn thành mã từ tài nguyên thư viện nội bộ, đồng thời cho phép người dùng đổi tên hoặc gỡ bỏ tài nguyên riêng tư mà không làm hỏng ứng dụng của thư viện. Các tài nguyên riêng tư được lọc ra khỏi quá trình hoàn thành mã và công cụ tìm lỗi mã nguồn sẽ nhắc nhở bạn khi bạn cố gắng tham chiếu một tài nguyên riêng tư.

Khi xây dựng một thư viện, Trình bổ trợ Android cho Gradle sẽ lấy các định nghĩa tài nguyên công khai và trích xuất các định nghĩa đó vào tệp public.txt. Tệp này sau đó được gói trong tệp AAR.

Những điểm cần lưu ý khi phát triển mô-đun thư viện

Khi bạn phát triển các mô-đun thư viện và ứng dụng phụ thuộc, hãy lưu ý đến các hành vi và giới hạn sau.

  • Các thư viện được hợp nhất theo thứ tự ưu tiên.

    Sau khi thêm tệp tham chiếu đến các mô-đun thư viện vào mô-đun của ứng dụng Android, bạn có thể đặt mức độ ưu tiên tương đối cho các mô-đun đó. Trong thời gian xây dựng, các thư viện sẽ được hợp nhất với từng ứng dụng một, bắt đầu từ mức ưu tiên thấp nhất đến mức cao nhất.

  • Tránh xung đột hợp nhất tài nguyên.

    Các công cụ xây dựng hợp nhất tài nguyên từ một mô-đun thư viện với các tài nguyên của một mô-đun ứng dụng phụ thuộc. Nếu một mã tài nguyên nhất định được xác định trong cả hai mô-đun, thì tài nguyên của ứng dụng sẽ được dùng.

    Nếu xảy ra xung đột giữa nhiều thư viện AAR, thì hệ thống sẽ sử dụng tài nguyên của thư viện được liệt kê đầu tiên trong danh sách phần phụ thuộc (ở gần nhất với phần đầu khối dependencies).

    Để tránh xung đột tài nguyên, hãy sử dụng các lớp R không mang tính chất bắc cầu. Nếu không thể sử dụng cách này, hãy cân nhắc dùng một tiền tố hoặc lược đồ đặt tên nhất quán khác dành riêng cho mô-đun (hoặc là duy nhất trên tất cả các mô-đun dự án).

  • Trong các bản dựng có nhiều mô-đun, các phần phụ thuộc JAR sẽ được coi là phần phụ thuộc bắc cầu.

    Khi bạn thêm phần phụ thuộc JAR vào một dự án thư viện sẽ tạo ra AAR, thì JAR này sẽ được mô-đun thư viện xử lý và đóng gói với AAR của mô-đun đó.

    Tuy nhiên, nếu dự án của bạn bao gồm một mô-đun thư viện mà một mô-đun ứng dụng dùng, thì mô-đun ứng dụng đó sẽ xem phần phụ thuộc JAR cục bộ của thư viện là một phần phụ thuộc bắc cầu. Trong trường hợp này, JAR cục bộ sẽ được xử lý bởi mô-đun ứng dụng dùng mô-đun đó, chứ không phải bằng mô-đun thư viện. Điều này giúp đẩy nhanh tốc độ cho các bản dựng gia tăng do các thay đổi mã của thư viện gây ra.

    Bạn cần phải giải quyết mọi xung đột tài nguyên Java do các phần phụ thuộc JAR cục bộ gây ra trong mô-đun ứng dụng dùng thư viện.

  • Một mô-đun thư viện có thể phụ thuộc vào một thư viện JAR bên ngoài.

    Bạn có thể phát triển một mô-đun thư viện phụ thuộc vào thư viện bên ngoài. Trong trường hợp này, mô-đun phụ thuộc phải xây dựng dựa vào một mục tiêu có bao gồm thư viện bên ngoài.

    Lưu ý rằng cả mô-đun thư viện và ứng dụng phụ thuộc đều phải khai báo thư viện bên ngoài trong tệp kê khai của cả mô-đun thư viện lẫn ứng dụng phụ thuộc đó, trong phần tử <uses-library>.

  • minSdkVersion của mô-đun ứng dụng phải bằng hoặc hơn phiên bản do thư viện xác định.

    Thư viện được biên dịch như một phần của mô-đun ứng dụng phụ thuộc, vì vậy, các API dùng trong mô-đun thư viện phải tương thích với phiên bản nền tảng mà mô-đun ứng dụng hỗ trợ.

  • Mỗi mô-đun thư viện tạo ra lớp R riêng.

    Khi bạn xây dựng các mô-đun ứng dụng phụ thuộc, các mô-đun thư viện sẽ được biên dịch vào tệp AAR rồi thêm vào mô-đun ứng dụng. Do đó, mỗi thư viện có lớp R riêng và được đặt tên theo tên gói của thư viện.

    Lớp R được tạo từ mô-đun chính và mô-đun thư viện được tạo trong tất cả các gói cần thiết, bao gồm cả gói của mô-đun chính và các gói của thư viện.

  • Một mô-đun thư viện có thể bao gồm tệp cấu hình ProGuard riêng.

    Nếu có dự án thư viện dùng để xây dựng và phát hành AAR, thì bạn có thể thêm tệp cấu hình ProGuard vào cấu hình bản dựng của thư viện. Nếu bạn làm như vậy, Trình bổ trợ Android cho Gradle sẽ áp dụng các quy tắc ProGuard mà bạn chỉ định. Các công cụ bản dựng sẽ nhúng tệp này trong tệp AAR được tạo cho mô-đun thư viện. Khi bạn thêm thư viện vào một mô-đun ứng dụng, tệp ProGuard của thư viện sẽ được thêm vào tệp cấu hình ProGuard (proguard.txt) của mô-đun ứng dụng.

    Bằng cách nhúng tệp ProGuard vào mô-đun thư viện, bạn giúp đảm bảo rằng các mô-đun ứng dụng phụ thuộc vào thư viện không phải cập nhật các tệp ProGuard theo cách thủ công để dùng thư viện của bạn. Khi xây dựng ứng dụng của bạn, hệ thống xây dựng Android Studio sẽ dùng các lệnh từ cả thư viện và mô-đun ứng dụng. Vì vậy, bạn không cần phải chạy trình rút gọn mã trên thư viện bằng một bước riêng biệt.

    Để thêm các quy tắc ProGuard vào dự án thư viện, hãy chỉ định tên của tệp bằng thuộc tính consumerProguardFiles bên trong khối defaultConfig của tệp build.gradle hoặc build.gradle.kts trong thư viện.

    Ví dụ: đoạn mã sau đây sẽ đặt lib-proguard-rules.txt làm tệp cấu hình ProGuard của thư viện:

    Groovy

    android {
        defaultConfig {
            consumerProguardFiles 'lib-proguard-rules.txt'
        }
        ...
    }

    Kotlin

    android {
        defaultConfig {
            consumerProguardFiles("lib-proguard-rules.txt")
        }
        ...
    }

    Tuy nhiên, nếu mô-đun thư viện của bạn là một phần của bản dựng nhiều mô-đun sẽ biên dịch thành APK và không tạo AAR, thì chỉ nên chạy quá trình rút gọn mã trên mô-đun ứng dụng mà sử dụng thư viện. Để tìm hiểu thêm về các quy tắc ProGuard và cách sử dụng các quy tắc đó, hãy đọc bài viết Rút gọn, làm rối mã nguồn và tối ưu hoá ứng dụng.

  • Quá trình kiểm thử mô-đun thư viện cũng gần giống như quá trình kiểm thử ứng dụng.

    Điểm khác biệt chính là thư viện và các phần phụ thuộc của thư viện đó sẽ được tự động thêm vào dưới dạng phần phụ thuộc của APK kiểm thử. Điều này có nghĩa là APK kiểm thử không chỉ bao gồm mã riêng của APK đó mà còn chứa AAR của thư viện và mọi phần phụ thuộc của APK đó. Do không có ứng dụng đang kiểm thử riêng biệt nào nên nhiệm vụ androidTest sẽ chỉ cài đặt (và gỡ cài đặt) APK kiểm thử.

    Khi hợp nhất nhiều tệp kê khai, Gradle sẽ thực hiện theo thứ tự ưu tiên mặc định và hợp nhất tệp kê khai của thư viện đó vào tệp kê khai chính của APK kiểm thử.

Cấu trúc của tệp AAR

Đuôi tệp của tệp AAR là .aar và loại cấu phần phần mềm Maven cũng là aar. Bản thân tệp này là tệp ZIP. Mục nhập bắt buộc duy nhất là /AndroidManifest.xml.

Tệp AAR cũng có thể bao gồm một hoặc nhiều mục nhập không bắt buộc sau đây: