Tworzenie biblioteki na Androida

Biblioteka Androida ma tę samą strukturę co moduł aplikacji na Androida. Zawiera wszystko, czego potrzeba do skompilowania aplikacji, w tym kod źródłowy, pliki zasobów i manifest Androida.

Jednak zamiast kompilowania 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 dla modułu aplikacji na Androida. W odróżnieniu od plików JAR pliki AAR zapewniają aplikacjom na Androida te funkcje:

  • Pliki AAR mogą zawierać zasoby Androida i plik manifestu, co umożliwia grupowanie wspólnych zasobów, takich jak układy i pliki drawable, a także klas i metod Kotlina lub Javy.
  • Pliki AAR mogą zawierać biblioteki C/C++, które są używane przez kod C/C++ w module aplikacji.

Moduł biblioteki jest przydatny w tych sytuacjach:

  • podczas tworzenia wielu aplikacji, które korzystają z tych samych komponentów, takich jak czynności, usługi lub układy interfejsu użytkownika;
  • podczas tworzenia aplikacji, która występuje w kilku wariantach pliku APK, np. w wersji bezpłatnej i płatnej, które mają wspólne główne komponenty.

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

Na tej stronie znajdziesz informacje o tworzeniu i używaniu modułu biblioteki 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 Tworzenie nowego modułu kliknij Biblioteka 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ępnić kod innym platformom, ale nie pozwala uwzględnić zasobów ani plików manifestu Androida, co jest bardzo przydatne w przypadku ponownego używania 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 potem 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 panel wyświetla 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 go przekształcić w moduł biblioteki w ten sposób:

  1. Jeśli używasz Groovy, otwórz plik build.gradle na poziomie modułu, a jeśli używasz skryptu Kotlin, otwórz plik build.gradle.kts.
  2. Usuń wiersz dotyczący applicationId. Tylko moduł aplikacji na Androida może zdefiniować tę wartość.
  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 Plik > Synchronizuj projekt z plikami Gradle.

Struktura modułu pozostaje taka sama, ale teraz działa on jako biblioteka Androida. W procesie kompilacji zamiast pliku APK zostanie utworzony plik AAR.

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

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

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

Korzystanie z biblioteki w ramach tego samego projektu

Aby użyć kodu nowej biblioteki Androida w innej aplikacji lub w modułach 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 Dodaj zależność modułu wybierz moduł biblioteki.

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

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

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

Groovy

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

Kotlin

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

Korzystanie z biblioteki w innych projektach

Zalecane jest udostępnianie zależności (plików JAR i AAR) za pomocą 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 Repozytoria zdalne.

Gdy biblioteka Androida zostanie opublikowana w repozytorium Maven, zostaną dodane metadane, aby zależności biblioteki zostały uwzględnione w kompilacji. Dzięki temu biblioteka może być automatycznie deduplikowana, jeśli jest używana w kilku miejscach.

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

  1. Kliknij Plik > Struktura projektu > zależności.
  2. Na karcie Zadeklarowane zależności kliknij , a następnie 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 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 ona wszystkich konfiguracji, a potem kliknij OK.

Sprawdź plik build.gradle lub build.gradle.kts aplikacji, aby potwierdzić, że deklaracja jest podobna 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, 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ść z pliku JAR.

  3. W oknie 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 dla wszystkich konfiguracji, 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 wyświetla się deklaracja podobna 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 Android Studio, dodaj ścieżkę do tej zależności w pliku build.gradle lub build.gradle.kts aplikacji. Może to obejmować np. te funkcje:

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, takie jak 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 dodano jeszcze publicznych zasobów, musisz utworzyć plik public.xml w katalogu res/values/ w bibliotece.

Poniższy przykładowy kod tworzy 2 publiczne zasoby ciągu 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 tylko do użytku wewnętrznego, użyj automatycznego mechanizmu wyznaczania zasobów prywatnych, deklarując co najmniej 1 zasób publiczny. Możesz też ustawić wszystkie zasoby jako prywatne, dodając pusty tag <public />. W ten sposób nic nie jest oznaczane jako publiczne, a 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 biblioteky otrzymywanie sugestii dotyczącej uzupełniania kodu z zasobów wewnętrznych biblioteki i umożliwia im zmianę nazwy lub usunięcie zasobów prywatnych bez zakłócania działania klientów biblioteki. Zasoby prywatne są odfiltrowywane z uzupełniania kodu, a narzędzie lint wyświetla ostrzeżenie, gdy próbujesz odwoływać się do zasobu prywatnego.

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

Wskazówki dotyczące tworzenia modułów biblioteki

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

  • Biblioteki są łączone według kolejności priorytetów.

    Po dodaniu do modułu aplikacji na Androida odwołań do modułów biblioteki możesz ustawić ich względną ważność. Podczas kompilacji biblioteki są scalane z aplikacją pojedynczo, zaczynając od biblioteki o najniższym priorytecie do tej o najwyższym.

  • Unikaj konfliktów podczas scalania zasobów.

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

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

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

  • W kompilacji wielomodułowej 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, moduł biblioteki przetworzy plik JAR i zapakuje go z plikiem AAR.

    Jeśli jednak Twój projekt zawiera moduł biblioteki, z którego korzysta moduł aplikacji, moduł aplikacji traktuje lokalną zależność JAR biblioteki jako zależność bierną. 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 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 zostać skompilowany na podstawie celu, który zawiera bibliotekę zewnętrzną.

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

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

    Biblioteka jest kompilowana jako część zależnego modułu aplikacji, 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ą klasę R.

    Gdy kompilujesz zależne moduły aplikacji, moduły biblioteki są kompilowane do pliku AAR, a potem dodawane do modułu aplikacji. Dlatego każda biblioteka ma własną klasę R, której nazwa odpowiada nazwie pakietu biblioteki.

    Klasa R wygenerowana z modułu głównego i modułu biblioteki jest tworzona we wszystkich niezbędnych 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 kompilowania i publikowania pliku AAR, możesz dodać plik konfiguracji ProGuard do konfiguracji kompilacji biblioteki. Jeśli tak, wtyczka Gradle na Androida zastosuje określone przez Ciebie reguły ProGuard. Narzędzia kompilacji umieszczają ten plik w wygenerowanym pliku AAR biblioteki. Gdy dodasz bibliotekę do modułu aplikacji, plik ProGuard biblioteki zostanie dołączony do pliku konfiguracyjnego ProGuard (proguard.txt) modułu aplikacji.

    Dzięki umieszczeniu w module biblioteki pliku ProGuard możesz zadbać o to, aby moduły aplikacji, które korzystają z Twojej biblioteki, nie musiały ręcznie aktualizować plików ProGuard. Gdy system kompilacji Android Studio kompiluje aplikację, używa dyrektyw zarówno z modułu aplikacji, jak i z biblioteki. Dlatego nie trzeba uruchamiać kompresora kodu na 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 w pliku build.gradle lub build.gradle.kts biblioteki.

    Na przykład ten fragment kodu ustawia lib-proguard-rules.txt jako plik konfiguracji ProGuarda 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, uruchom kod zwężający tylko w module aplikacji, który korzysta z biblioteki. Więcej informacji o regułach ProGuard i ich zastosowaniu znajdziesz w artykule Skrócenie, zaciemnienie i optymalizacja aplikacji.

  • Testowanie modułu biblioteki przebiega 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 pliku APK testowego. 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 aplikacji do testowania, zadanie androidTest instaluje (i odinstalowuje) tylko testowy plik APK.

    Podczas łączenia wielu plików manifestu Gradle stosuje domyślną kolejność priorytetów i łączy plik manifestu biblioteki z głównym plikiem manifestu pliku APK testowego.

Anatomia pliku AAR

Rozszerzenie pliku AAR to .aar, a typ artefaktu Maven to również aar. 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: