Tworzenie biblioteki na Androida

Biblioteka na 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ć się do pliku APK, który działa na urządzeniu, biblioteka na Androida kompiluje się do pliku Android Archive (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ą te funkcje w przypadku aplikacji na Androida:

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

Moduł biblioteki jest przydatny w tych sytuacjach:

  • podczas tworzenia wielu aplikacji, które używają tych samych komponentów, takich jak aktywności, usługi lub układy interfejsu
  • podczas tworzenia aplikacji, która występuje w wielu wariantach APK, np. w wersji bezpłatnej i płatnej, które mają wspólne komponenty podstawowe

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

Na tej stronie dowiesz się, jak utworzyć i używać modułu biblioteki na Androida. Więcej informacji o publikowaniu biblioteki znajdziesz w artykule Publikowanie biblioteki.

Tworzenie modułu biblioteki

Aby utworzyć nowy moduł biblioteki w projekcie:

  1. Kliknij Plik > Nowy > Nowy moduł.
  2. W wyświetlonym oknie Utwórz nowy moduł kliknij Biblioteka na Androida, a potem kliknij 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 dołączanie zasobów Androida ani plików manifestu, co jest bardzo przydatne w przypadku ponownego użycia kodu w projektach na Androida. Ten przewodnik skupia się na tworzeniu bibliotek na 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 wyświetla się widok Android.

Konwertowanie modułu aplikacji na moduł biblioteki

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

  1. Otwórz plik build.gradle na poziomie modułu, jeśli używasz Groovy, lub plik build.gradle.kts jeśli używasz skryptu Kotlin.
  2. Usuń wiersz applicationId. Tylko moduł aplikacji na Androida może go zdefiniować.
  3. Znajdź blok `plugins` u góry pliku, który wygląda tak:

    Dynamiczny

      plugins {
          id 'com.android.application'
      }
      

    Kotlin

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

    Zmień go na:

    Dynamiczny

      plugins {
          id 'com.android.library'
      }
      

    Kotlin

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

Struktura modułu pozostaje taka sama, ale teraz działa on jako biblioteka na Androida. Kompilacja tworzy plik AAR zamiast pliku APK.

Aby utworzyć plik AAR, wybierz moduł biblioteki w oknie Projekt i kliknij Kompilacja > Kompiluj APK.

Dodawanie zależności za pomocą okna Struktura projektu

Do projektu możesz dodawać zależności za pomocą okna Struktura projektu. W kolejnych sekcjach opisujemy, jak używać tego okna do dodawania zależności.

Używanie biblioteki w tym samym projekcie

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

  1. Otwórz 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 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 implementation (implementacja), jeśli dotyczy ona 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:

Dynamiczny

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

Kotlin

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

Używanie biblioteki w innych projektach

Zalecanym sposobem udostępniania zależności (JAR i AAR) jest używanie repozytorium Maven hostowanego w usłudze takiej jak Maven Centrallub w strukturze katalogów na dysku lokalnym. Więcej informacji o korzystaniu z repozytoriów Maven znajdziesz w artykule Repozytoria zdalne.

Gdy biblioteka na Androida jest publikowana w repozytorium Maven, dołączane są metadane, dzięki czemu zależności biblioteki są uwzględniane w kompilacji. Pozwala to na automatyczne usuwanie duplikatów biblioteki, jeśli jest ona używana w wielu miejscach.

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

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

  3. W oknie Dodaj zależność biblioteki użyj pola wyszukiwania, aby znaleźć bibliotekę, którą chcesz dodać. Ten formularz przeszukuje repozytoria określone w w bloku w settings.gradle lub settings.gradle.kts pliku.dependencyResolutionManagement { repositories {...}}

    Dodawanie zależności biblioteki w oknie Struktura projektu

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

Sprawdź plik build.gradle lub build.gradle.kts aplikacji, aby upewnić się, że znajduje się w nim deklaracja podobna do tej (w zależności od wybranej konfiguracji kompilacji):

Dynamiczny

  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 na Androida w innym module aplikacji:

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

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

    Dodawanie zależności AAR w oknie Struktura projektu

    Sprawdź plik build.gradle lub build.gradle.kts aplikacji, aby upewnić się, że znajduje się w nim deklaracja podobna do tej (w zależności od wybranej konfiguracji kompilacji ):

    Dynamiczny

      implementation files('my_path/my_lib.aar')

    Kotlin

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

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

Dynamiczny

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. Domyślnie wszystkie zasoby w bibliotece są 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 zasobów publicznych, musisz utworzyć plik public.xml w katalogu res/values/ biblioteki.

Ten przykładowy kod tworzy 2 publiczne zasoby tekstowe o nazwach mylib_app_name i mylib_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 tylko 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 <public /> tag. Nie oznacza to niczego jako publicznego i sprawia, że wszystkie zasoby są prywatne.

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

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

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 aplikacji zależnych pamiętaj o tych zachowaniach i ograniczeniach.

  • Biblioteki są scalane 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, gdy istnieją zasoby o tej samej nazwie.

  • Unikaj konfliktów scalania zasobów.

    Narzędzia kompilacji scalają zasoby z modułu biblioteki z zasobami zależnego modułu aplikacji. 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żywany jest zasób z biblioteki wymienionej jako pierwszej na liście zależności (najbliżej góry 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 unikalny we wszystkich modułach projektu).

  • W kompilacjach 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 plik AAR, plik JAR jest przetwarzany przez moduł biblioteki i pakowany z plikiem AAR.

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

    Wszelkie konflikty zasobów Java spowodowane lokalnymi zależnościami JAR muszą zostać rozwiązane w module aplikacji, który używa biblioteki.

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

    Możesz utworzyć moduł biblioteki, który zależy od biblioteki zewnętrznej. W takim przypadku moduł zależny musi być kompilowany pod kątem celu, który zawiera bibliotekę zewnętrzną.

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

  • Wartość minSdkVersion modułu aplikacji musi być równa lub większa niż wersja zdefiniowana przez bibliotekę.

    Biblioteka jest kompilowana jako część zależnego modułu aplikacji, dlatego interfejsy API używane w module biblioteki muszą być zgodne z wersją platformy obsługiwaną przez moduł aplikacji.

  • Każdy moduł biblioteki tworzy własną klasę R

    Podczas kompilowania zależnych modułów 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 obsługi Gradle stosuje określone przez Ciebie reguły ProGuard. Narzędzia kompilacji osadzają ten plik w wygenerowanym pliku AAR dla modułu biblioteki. Gdy dodasz bibliotekę do modułu aplikacji, plik ProGuard biblioteki zostanie dołączony do pliku konfiguracji ProGuard (proguard.txt) modułu aplikacji.

    Osadzając plik ProGuard w module biblioteki, pomagasz zapewnić, że moduły aplikacji, które zależą od Twojej biblioteki, nie będą musiały ręcznie aktualizować swoich plików ProGuard, aby używać Twojej biblioteki. Gdy system kompilacji Android Studio kompiluje Twoją aplikację, używa dyrektyw z modułu aplikacji i biblioteki. Nie musisz więc uruchamiać narzędzia do zmniejszania kodu w bibliotece 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 biblioteki build.gradle lub build.gradle.kts.

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

    Dynamiczny

    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, uruchom zmniejszanie kodu tylko w module aplikacji, który używa biblioteki. Więcej informacji o regułach ProGuard i ich użyciu znajdziesz w artykule Zmniejszanie, zaciemnianie kodu 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 jej 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 stosuje domyślną kolejność priorytetów i scala manifest biblioteki z głównym manifestem testowego pliku APK.

Struktura pliku AAR

Rozszerzenie pliku AAR to .aar, a typ artefaktu Maven to aar też. Sam plik jest plikiem ZIP. Jedynym obowiązkowym wpisem jest /AndroidManifest.xml.

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