Tworzenie biblioteki na Androida

Biblioteka Androida jest strukturalnie taka sama jak moduł aplikacji na Androida. Zawiera wszystko, co jest potrzebne do utworzenia aplikacji, w tym kod źródłowy, pliki zasobów i manifest Androida.

Zamiast kompilować bibliotekę na Androida do pliku APK, który działa na urządzeniu, kompilujesz ją do pliku archiwum Androida (AAR), którego możesz używać jako zależności modułu aplikacji na Androida. W przeciwieństwie do plików JAR pliki AAR oferują w przypadku aplikacji na Androida te funkcje:

  • Pliki AAR mogą zawierać zasoby Androida i plik manifestu, co umożliwia dołączanie zasobów współdzielonych, takich jak układy i elementy rysowalne, oprócz klas i metod w języku Kotlin lub Java.
  • Pliki AAR mogą zawierać biblioteki C/C++ do użytku przez kod C/C++ modułu aplikacji.

Moduł biblioteki jest przydatny w tych sytuacjach:

  • Podczas tworzenia wielu aplikacji, które korzystają z tych samych komponentów, np. aktywności, usług lub układów interfejsu
  • Podczas tworzenia aplikacji, która występuje w kilku wersjach APK, np. bezpłatnej i płatnej, i która ma wspólne komponenty

W obu przypadkach przenieś pliki, których chcesz ponownie użyć, do modułu biblioteki, a następnie dodaj bibliotekę jako zależność dla każdego modułu aplikacji.

Z tego artykułu dowiesz się, jak utworzyć i używać modułu biblioteki Androida. Więcej informacji o publikowaniu biblioteki znajdziesz w artykule Publikowanie biblioteki.

Tworzenie modułu biblioteki

Aby utworzyć w projekcie nowy moduł biblioteki, wykonaj te czynności:

  1. Kliknij Plik > Nowy > Nowy moduł.
  2. W wyświetlonym oknie Create New Module (Utwórz nowy moduł) kliknij Android Library (Biblioteka Androida), a następnie kliknij Next (Dalej).

    Możesz też utworzyć bibliotekę Kotlin lub Java, która tworzy tradycyjny plik JAR. Plik JAR jest przydatny w wielu projektach, zwłaszcza gdy chcesz udostępniać kod innym platformom, ale nie pozwala na uwzględnianie zasobów Androida ani plików manifestu, co jest bardzo przydatne w przypadku ponownego wykorzystywania kodu w projektach na Androida. Ten przewodnik koncentruje się na tworzeniu bibliotek Androida.

  3. Nadaj bibliotece nazwę i wybierz minimalną wersję pakietu SDK dla kodu w bibliotece, a następnie kliknij Zakończ.

Po zakończeniu synchronizacji projektu Gradle moduł biblioteki pojawi się w panelu Projekt. Jeśli nie widzisz nowego folderu modułu, sprawdź, czy w panelu jest wyświetlany widok Androida.

Konwertowanie modułu aplikacji na moduł biblioteki

Jeśli masz istniejący moduł aplikacji z kodem, którego chcesz ponownie użyć, możesz przekształcić go w moduł biblioteki w ten sposób:

  1. Otwórz plik build.gradle na poziomie modułu, jeśli używasz skryptu Groovy, lub plik build.gradle.kts, jeśli używasz skryptu Kotlin.
  2. Usuń wiersz dla applicationId. Może to zdefiniować tylko moduł aplikacji na Androida.
  3. U góry pliku znajdź blok „plugins”, który wygląda tak:

    Groovy

      plugins {
          id 'com.android.application'
      }
      

    Kotlin

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

    Zmień go na:

    Groovy

      plugins {
          id 'com.android.library'
      }
      

    Kotlin

      plugins {
          id("com.android.library")
      }
      
  4. Zapisz plik i kliknij File > Sync Project with Gradle Files (Plik > Synchronizuj projekt z plikami Gradle).

Struktura modułu pozostaje bez zmian, ale teraz działa on jako biblioteka Androida. W wyniku kompilacji powstanie plik AAR zamiast pliku APK.

Gdy chcesz utworzyć plik AAR, wybierz moduł biblioteki w oknie Projekt i kliknij Utwórz > Utwórz APK.

Dodawanie zależności w oknie dialogowym Struktura projektu

Aby dodać zależności do projektu, możesz użyć okna Struktura projektu. W sekcjach poniżej opisujemy, jak za pomocą tego okna dodawać zależności.

Korzystanie z biblioteki w tym samym projekcie

Aby użyć kodu nowej biblioteki Androida w innej aplikacji lub module biblioteki w tym samym projekcie, dodaj zależność na poziomie projektu:

  1. Kliknij Plik> Struktura projektu > Zależności.
  2. Wybierz moduł, do którego chcesz dodać bibliotekę.
  3. Na karcie Zadeklarowane zależności kliknij i w menu wybierz Zależność modułu.

  4. W oknie Add Module Dependency (Dodaj zależność modułu) wybierz moduł biblioteki.

    Dodawanie zależności modułu w oknie Struktura projektu

  5. Wybierz konfigurację, która wymaga tej zależności, lub wybierz implementację, jeśli dotyczy to wszystkich konfiguracji, a następnie kliknij OK.

Android Studio edytuje plik build.gradle lub build.gradle.kts modułu, aby dodać zależność w tej postaci:

Groovy

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

Kotlin

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

Korzystanie z biblioteki w innych projektach

Zalecanym sposobem udostępniania zależności (plików JAR i AAR) jest repozytorium Maven, które może być hostowane w usłudze takiej jak Maven Central lub mieć strukturę katalogów na dysku lokalnym. Więcej informacji o korzystaniu z repozytoriów Maven znajdziesz w artykule Zdalne repozytoria.

Gdy biblioteka Androida jest publikowana w repozytorium Maven, zawiera metadane, dzięki czemu zależności biblioteki są uwzględniane w kompilacji korzystającej z niej. Dzięki temu biblioteka może być automatycznie usuwana, jeśli jest używana w wielu miejscach.

Aby użyć kodu biblioteki Androida w innym module aplikacji w innym projekcie, wykonaj te czynności:

  1. Kliknij Plik> Struktura projektu > Zależności.
  2. Na karcie Zadeklarowane zależności kliknij i w menu wybierz Zależność biblioteki.

  3. W oknie Add Library Dependency (Dodaj zależność biblioteki) użyj pola wyszukiwania, aby znaleźć bibliotekę do dodania. Ten formularz przeszukuje repozytoria określone w bloku dependencyResolutionManagement { repositories {...}} w pliku settings.gradle lub settings.gradle.kts.

    Dodawanie zależności biblioteki w oknie Struktura projektu

  4. Wybierz konfigurację, która wymaga tej zależności, lub wybierz implementację, jeśli dotyczy to wszystkich konfiguracji, a następnie kliknij OK.

Sprawdź plik build.gradle lub build.gradle.kts aplikacji, aby upewnić się, że zawiera deklarację podobną do tej (w zależności od wybranej konfiguracji kompilacji):

Groovy

  implementation 'com.example:examplelibrary:1.0.0'

Kotlin

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

Dodawanie pliku AAR lub JAR jako zależności

Aby użyć kodu biblioteki Androida w innym module aplikacji:

  1. Kliknij Plik> Struktura projektu > Zależności.
  2. Na karcie Zadeklarowane zależności kliknij  i w menu wybierz Zależność JAR.

  3. W oknie Add Jar/Aar Dependency (Dodaj zależność JAR/AAR) wpisz ścieżkę do pliku AAR lub JAR, a potem wybierz konfigurację, do której ma się odnosić zależność. Jeśli biblioteka ma być dostępna we wszystkich konfiguracjach, wybierz konfigurację implementacji.

    Dodawanie zależności AAR w oknie dialogowym Struktura projektu

    Sprawdź plik build.gradle lub build.gradle.kts aplikacji, aby potwierdzić, że zawiera deklarację podobną do tej (w zależności od wybranej konfiguracji kompilacji):

    Groovy

      implementation files('my_path/my_lib.aar')

    Kotlin

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

Aby zaimportować zależność w kompilacji Gradle uruchomionej poza Androidem Studio, dodaj ścieżkę do zależności w pliku build.gradle lub build.gradle.kts aplikacji. Na przykład:

Groovy

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

Kotlin

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

Więcej informacji o dodawaniu zależności Gradle znajdziesz w artykule Dodawanie zależności kompilacji.

Deklarowanie zasobu publicznego

Zasoby obejmują wszystkie pliki w katalogu res/ projektu, np. obrazy. Wszystkie zasoby w bibliotece są domyślnie publiczne. Aby wszystkie zasoby były domyślnie prywatne, musisz zdefiniować co najmniej 1 konkretny atrybut jako publiczny.

Aby zadeklarować zasób publiczny, dodaj deklarację <public> do pliku public.xml biblioteki. Jeśli nie masz jeszcze dodanych zasobów publicznych, musisz utworzyć plik public.xml w katalogu res/values/ biblioteki.

Poniższy przykładowy kod tworzy 2 publiczne zasoby ciągów znaków o nazwach mylib_app_namemylib_public_string:

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

Aby uniemożliwić użytkownikom biblioteki dostęp do zasobów przeznaczonych wyłącznie do użytku wewnętrznego, użyj tego mechanizmu automatycznego oznaczania jako prywatne, deklarując co najmniej 1 zasób publiczny. Możesz też ustawić wszystkie zasoby jako prywatne, dodając pusty tag <public />. Ta opcja nie oznacza niczego jako publicznego i sprawia, że wszystkie zasoby są prywatne.

Wszystkie zasoby, które mają być widoczne dla programistów korzystających z Twojej biblioteki, powinny być publiczne.

Ustawienie atrybutów jako prywatnych uniemożliwia użytkownikom biblioteki otrzymywanie sugestii dotyczących uzupełniania kodu z wewnętrznych zasobów biblioteki i pozwala im zmieniać nazwy lub usuwać prywatne zasoby bez powodowania problemów u klientów biblioteki. Prywatne zasoby są odfiltrowywane z funkcji uzupełniania kodu, a narzędzie lint ostrzega, gdy próbujesz odwołać się do prywatnego zasobu.

Podczas tworzenia biblioteki wtyczka Androida do obsługi Gradle pobiera definicje zasobów publicznych i wyodrębnia je do pliku public.txt, który jest następnie pakowany w pliku AAR.

Uwagi dotyczące tworzenia modułów biblioteki

Podczas tworzenia modułów biblioteki i zależnych aplikacji pamiętaj o tych zachowaniach i ograniczeniach.

  • Biblioteki są łączone w kolejności priorytetu.

    Po dodaniu odwołań do modułów biblioteki w module aplikacji na Androida możesz ustawić ich względny priorytet. Podczas kompilacji biblioteki są scalane z aplikacją pojedynczo, od najniższego do najwyższego priorytetu.

    Odwołania do zasobów w bibliotece będą odnosić się do scalonego zasobu, a niekoniecznie do zasobu biblioteki. Moduł biblioteki nie może wymuszać używania własnych zasobów zamiast zasobów aplikacji lub innych bibliotek, jeśli istnieją zasoby o tej samej nazwie.

  • Unikaj konfliktów scalania zasobów.

    Narzędzia do kompilacji scalają zasoby z modułu biblioteki z zasobami modułu aplikacji zależnej. Jeśli dana nazwa zasobu jest zdefiniowana w obu modułach, używany jest zasób z aplikacji.

    Jeśli wystąpią konflikty między kilkoma bibliotekami AAR, użyty zostanie zasób z biblioteki wymienionej jako pierwszej na liście zależności (najbliżej początku bloku dependencies).

    Aby uniknąć konfliktów zasobów, użyj prefiksu lub innego spójnego schematu nazewnictwa, który jest unikalny dla modułu (lub jest unikalny we wszystkich modułach projektu).

  • W przypadku kompilacji wielomodułowych zależności JAR są traktowane jako zależności pośrednie.

    Gdy dodasz zależność JAR do projektu biblioteki, który generuje AAR, plik JAR zostanie przetworzony przez moduł biblioteki i spakowany z plikiem AAR.

    Jeśli jednak projekt zawiera moduł biblioteki, który jest używany przez moduł aplikacji, moduł aplikacji traktuje lokalną zależność JAR biblioteki jako zależność przechodnią. W tym przypadku lokalny plik JAR jest przetwarzany przez moduł aplikacji, który go używa, a nie przez moduł biblioteki. Przyspiesza to przyrostowe kompilacje spowodowane zmianami w kodzie biblioteki.

    Wszelkie konflikty zasobów Java spowodowane lokalnymi zależnościami JAR należy rozwiązać w module aplikacji, który korzysta z biblioteki.

  • Moduł biblioteki może być zależny od zewnętrznej biblioteki JAR.

    Możesz opracować moduł biblioteki, który jest zależny od biblioteki zewnętrznej. W takim przypadku moduł zależny musi być zbudowany na podstawie celu, który zawiera bibliotekę zewnętrzną.

    Zarówno moduł biblioteki, jak i zależna aplikacja muszą zadeklarować bibliotekę zewnętrzną w swoich plikach manifestu w elemencie <uses-library>.

  • Wersja minSdkVersion modułu aplikacji musi być równa wersji zdefiniowanej przez bibliotekę lub od niej większa.

    Biblioteka jest kompilowana w ramach modułu aplikacji zależnej, więc interfejsy API używane w module biblioteki muszą być zgodne z wersją platformy, którą obsługuje moduł aplikacji.

  • Każdy moduł biblioteki tworzy własną Rklasę.

    Gdy tworzysz zależne moduły aplikacji, moduły biblioteki są kompilowane do pliku AAR, a następnie dodawane do modułu aplikacji. Dlatego każda biblioteka ma własną klasę R o nazwie zgodnej z nazwą pakietu biblioteki.

    Klasa R wygenerowana z modułu głównego i modułu biblioteki jest tworzona we wszystkich potrzebnych pakietach, w tym w pakiecie modułu głównego i pakietach bibliotek.

  • Moduł biblioteki może zawierać własny plik konfiguracji ProGuard.

    Jeśli masz projekt biblioteki, którego używasz do tworzenia i publikowania pliku AAR, możesz dodać plik konfiguracji ProGuard do konfiguracji kompilacji biblioteki. W takim przypadku wtyczka Androida do Gradle zastosuje określone przez Ciebie reguły ProGuard. Narzędzia do kompilacji osadzają ten plik w wygenerowanym pliku AAR modułu biblioteki. Gdy dodasz bibliotekę do modułu aplikacji, plik ProGuard biblioteki zostanie dołączony do pliku konfiguracyjnego ProGuard (proguard.txt) modułu aplikacji.

    Osadzając plik ProGuard w module biblioteki, możesz mieć pewność, że moduły aplikacji, które zależą od Twojej biblioteki, nie będą musiały ręcznie aktualizować swoich plików ProGuard, aby z niej korzystać. Gdy system kompilacji Android Studio kompiluje aplikację, korzysta z dyrektyw z modułu aplikacji i biblioteki. Nie musisz więc uruchamiać narzędzia do zmniejszania kodu w osobnym kroku.

    Aby dodać reguły ProGuard do projektu biblioteki, określ nazwę pliku za pomocą właściwości consumerProguardFiles w bloku defaultConfig pliku build.gradle lub build.gradle.kts biblioteki.

    Na przykład ten fragment kodu ustawia lib-proguard-rules.txt jako plik konfiguracji ProGuard biblioteki:

    Groovy

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

    Kotlin

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

    Jeśli jednak moduł biblioteki jest częścią kompilacji wielomodułowej, która kompiluje się do pliku APK i nie generuje pliku AAR, zmniejsz kod tylko w module aplikacji, który korzysta z biblioteki. Więcej informacji o regułach ProGuard i ich używaniu znajdziesz w artykule Zmniejszanie, zaciemnianie i optymalizowanie aplikacji.

  • Testowanie modułu biblioteki jest prawie takie samo jak testowanie aplikacji.

    Główna różnica polega na tym, że biblioteka i jej zależności są automatycznie uwzględniane jako zależności testowego pliku APK. Oznacza to, że testowy plik APK zawiera nie tylko własny kod, ale też plik AAR biblioteki i wszystkie jego zależności. Ponieważ nie ma osobnej testowanej aplikacji, zadanie androidTest instaluje (i odinstalowuje) tylko testowy plik APK.

    Podczas scalania wielu plików manifestu Gradle postępuje zgodnie z domyślną kolejnością priorytetów i scala plik manifestu biblioteki z głównym plikiem manifestu testowego pliku APK.

Anatomia pliku AAR

Rozszerzenie pliku AAR to .aar, a typ artefaktu Maven to również aar. Sam plik jest plikiem ZIP. Jedyny obowiązkowy wpis to /AndroidManifest.xml.

Plik AAR może też zawierać co najmniej 1 z tych opcjonalnych wpisów: