Tworzenie biblioteki na Androida

Struktura biblioteki Androida jest 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 plik manifestu Androida.

Jednak zamiast kompilować do pliku APK działającego na urządzeniu, biblioteka Androida kompiluje się do pliku Android Archive (AAR), którego można używać jako zależności dla modułu aplikacji na Androida. W przeciwieństwie do plików JAR pliki AAR oferują w aplikacjach na Androida te funkcje:

  • Pliki AAR mogą zawierać zasoby Androida i plik manifestu, który umożliwia łączenie zasobów współdzielonych, takich jak układy i elementy rysowane, jak również do klas i metod Kotlin lub Java.
  • Pliki AAR mogą zawierać biblioteki C/C++ do wykorzystania w kodzie C/C++ modułu aplikacji.

Moduł biblioteki jest przydatny w tych sytuacjach:

  • Gdy tworzysz wiele aplikacji korzystających z tych samych komponentów, np. aktywności, usług czy układów interfejsu
  • Gdy tworzysz aplikację występującą w wielu odmianach pliku APK, np. w wersji bezpłatnej i płatnej, które mają takie same podstawowe komponenty.

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

Ta strona wyjaśnia, jak utworzyć moduł biblioteki na Androidzie i jak go używać. Wskazówki na temat publikowania biblioteki znajdziesz w artykule Publikowanie biblioteki.

Tworzenie modułu biblioteki

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

  1. Kliknij File > New > New Module (Plik > Nowy > Nowy moduł).
  2. W wyświetlonym oknie 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 pozwala na utworzenie tradycyjnego pliku JAR. Plik JAR jest przydatny w wielu projektach – szczególnie wtedy, gdy chcesz udostępniać kod na innych platformach. Nie pozwala on jednak dodawać zasobów Androida ani plików manifestu, co jest bardzo przydatne w przypadku ponownego użycia kodu w projektach Androida. Ten przewodnik dotyczy tworzenia bibliotek Androida.

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

Po zakończeniu synchronizacji projektu Gradle moduł biblioteki pojawi się w panelu Projekt. Jeśli nie widzisz folderu nowego modułu, sprawdź, czy 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 w następujący sposób:

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

    Odlotowy

      plugins {
          id 'com.android.application'
      }
      

    Kotlin

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

    Zmień go na taki:

    Odlotowy

      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 bez zmian, ale teraz działa jak biblioteka Androida. Zamiast pliku APK tworzy ona plik AAR.

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

Dodawanie zależności w oknie Struktura projektu

Zależności do projektu możesz dodać w oknie Struktura projektu. W sekcjach poniżej dowiesz się, jak dodawać zależności za pomocą okna dialogowego.

Używanie biblioteki z poziomu tego samego projektu

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ł, w którym chcesz dodać bibliotekę.
  3. Na karcie Deklarowane zależności kliknij i z menu wybierz Zależność modułu.

  4. W oknie Dodaj zależność modułu wybierz moduł biblioteki.

    Dodaj zależność modułu w oknie
Struktura projektu

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

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

Odlotowy

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

Kotlin

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

Używaj swojej biblioteki w innych projektach

Zalecanym sposobem udostępniania zależności (JAR i AAR) jest użycie repozytorium Maven hostowanego w usłudze, takiej jak Maven Central, lub w strukturze katalogów na dysku lokalnym. Więcej informacji o używaniu repozytoriów Maven znajdziesz w artykule Zdalne repozytoria.

Gdy biblioteka Androida jest publikowana w repozytorium Maven, metadane są uwzględniane, tak aby zależności biblioteki były uwzględniane w używanej kompilacji. Umożliwi to automatyczne usuwanie duplikatów z biblioteki, jeśli jest ona używana w wielu miejscach.

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

  1. Kliknij Plik > Struktura projektu > Zależności.
  2. Na karcie Deklarowane zależności kliknij i w menu wybierz Zależność od 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 bloku dependencyResolutionManagement { repositories {...}} w pliku settings.gradle lub settings.gradle.kts.

    Dodaj zależność z biblioteką w oknie
Struktura projektu

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

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

Odlotowy

  implementation 'com.example:examplelibrary:1.0.0'

Kotlin

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

Dodawanie AAR lub JAR jako zależności

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

  1. Kliknij Plik > Struktura projektu > Zależności.
  2. Na karcie Deklarowane 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 zastosowanie zależność. Jeśli biblioteka ma być dostępna dla wszystkich konfiguracji, wybierz konfigurację implementacji.

    Dodaj zależność AAR w oknie struktury projektu

    Sprawdź w pliku build.gradle lub build.gradle.kts aplikacji, czy wyświetla się deklaracja podobna do tej (w zależności od wybranej konfiguracji kompilacji):

    Odlotowy

      implementation files('my_path/my_lib.aar')
    

    Kotlin

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

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

Odlotowy

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 o dodawaniu zależności kompilacji.

Deklarowanie zasobu publicznego

Zasoby obejmują wszystkie pliki znajdujące się w katalogu res/ projektu, np. obrazy. Wszystkie zasoby w bibliotece są domyślnie publiczne. Aby domyślnie ustawić wszystkie zasoby jako prywatne, musisz zdefiniować co najmniej 1 określony atrybut jako publiczny.

Aby zadeklarować zasób publiczny, dodaj deklarację <public> do pliku public.xml swojej biblioteki. Jeśli zasoby publiczne nie są jeszcze dodawane, 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 Twojej biblioteki dostęp do zasobów przeznaczonych tylko do użytku wewnętrznego, użyj tego automatycznego mechanizmu prywatnego oznaczania przez zadeklarowanie co najmniej 1 zasobu publicznego. Możesz też oznaczyć wszystkie zasoby jako prywatne, dodając pusty tag <public />. Nie oznaczy to niczego jako publicznego, przez co wszystkie zasoby staną się prywatne.

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

Gdy ustawisz atrybuty jako prywatne, użytkownicy Twojej biblioteki nie będą otrzymywać sugestii uzupełniania kodu z zasobów biblioteki wewnętrznej, a użytkownicy będą mogli zmieniać nazwy zasobów prywatnych lub je usuwać bez naruszania ich klientów. Zasoby prywatne są odfiltrowywane, gdy nie można uzupełniać kodu, a narzędzie Linting ostrzega Cię, 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 na temat programowania modułów biblioteki

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

  • Biblioteki są scalane w kolejności zgodnej z priorytetem.

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

  • Unikaj konfliktów scalania zasobów.

    Narzędzia do tworzenia scalają zasoby z modułu biblioteki z zasobami z modułu aplikacji. Jeśli dany identyfikator zasobu jest zdefiniowany w obu modułach, używany będzie zasób z aplikacji.

    Jeśli występują konflikty między wieloma bibliotekami AAR, używany jest zasób z biblioteki wymienionej jako pierwsza na liście zależności (najbliższym początku bloku dependencies).

    Aby uniknąć konfliktów zasobów, używaj nieprzechodnich klas R. Jeśli to niemożliwe, rozważ zastosowanie prefiksu lub innego spójnego schematu nazewnictwa, które jest unikalne dla danego modułu (lub jest unikalne dla wszystkich modułów projektu).

  • W kompilacjach wielomodułowych zależności JAR są traktowane jako zależności przechodnie.

    Gdy dodajesz zależność JAR do projektu biblioteki, który generuje AAR, plik JAR jest przetwarzany przez moduł biblioteki i pakowany z jego AAR.

    Jeśli jednak projekt zawiera moduł biblioteki, który jest zużywany przez moduł aplikacji, moduł ten traktuje lokalną zależność JAR biblioteki jako zależność przejściową. W tym 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.

    Wszystkie konflikty zasobów Javy spowodowane przez lokalne zależności JAR muszą zostać rozwiązane w module aplikacji, który korzysta z biblioteki.

  • Moduł biblioteki może korzystać z zewnętrznej biblioteki JAR.

    Możesz opracować moduł biblioteki zależny od biblioteki zewnętrznej. W takim przypadku moduł zależny musi utworzyć w oparciu o element docelowy, który zawiera bibliotekę zewnętrzną.

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

  • Wartość minSdkVersion modułu aplikacji musi być równa wersji zdefiniowanej w bibliotece lub od niej większa.

    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ługiwanej przez moduł aplikacji.

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

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

    Klasa R generowana 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 konfiguracyjny ProGuard.

    Jeśli masz projekt biblioteki, którego używasz do skompilowania i opublikowania AAR, możesz dodać plik konfiguracji ProGuard do konfiguracji kompilacji biblioteki. Jeśli to zrobisz, wtyczka Androida do obsługi Gradle zastosuje określone przez Ciebie reguły ProGuard. Narzędzia do kompilacji umieszczają ten plik w wygenerowanym pliku AAR dla modułu biblioteki. Gdy dodasz bibliotekę do modułu aplikacji, jej plik ProGuard zostanie dołączony do pliku konfiguracyjnego ProGuard (proguard.txt) modułu aplikacji.

    Umieszczając plik ProGuard w module biblioteki, sprawiasz, że moduły aplikacji, które korzystają z Twojej biblioteki, nie muszą ręcznie aktualizować swoich plików ProGuard, aby mogły korzystać z biblioteki. Gdy system kompilacji Android Studio tworzy aplikację, używa instrukcji z modułu aplikacji i biblioteki. Nie trzeba więc uruchamiać w bibliotece kompresora 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 konfiguracyjny ProGuard biblioteki:

    Odlotowy

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

    Kotlin

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

    Jeśli jednak moduł biblioteki jest częścią kompilacji składającej się z wielu modułów, która kompiluje się do pliku APK i nie generuje AAR, uruchom zmniejszając kod tylko na tym module aplikacji, który przetwarza bibliotekę. Więcej informacji o regułach ProGuard i ich wykorzystaniu znajdziesz w artykule Zmniejszanie, zaciemnianie i optymalizowanie aplikacji.

  • Testowanie modułu biblioteki jest prawie tak 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 pakietu APK. Oznacza to, że testowy pakiet APK zawiera nie tylko własny kod, ale też AAR biblioteki i wszystkie zależności. Nie ma osobnej aplikacji w trakcie testowania, dlatego zadanie androidTest instaluje (i odinstalowuje) tylko testowy plik APK.

    Podczas scalania wielu plików manifestu Gradle przestrzega domyślnej kolejności priorytetów i scala plik manifestu biblioteki z głównym plikiem manifestu testowego pakietu APK.

Struktura pliku AAR

Rozszerzenie pliku AAR to .aar, a typ artefaktu Maven również to aar. Jest to plik ZIP. Jedyna obowiązkowa pozycja to /AndroidManifest.xml.

Plik AAR może też zawierać 1 lub więcej z tych pozycji opcjonalnych: