Tworzenie biblioteki na Androida

Biblioteka Androida ma taką samą strukturę jak moduł aplikacji na Androida. Zawiera wszystkie elementy potrzebne do utworzenia aplikacji, w tym kod źródłowy, pliki zasobów i plik manifestu na Androida.

Biblioteka Androida nie kompiluje się jednak w formie pliku APK, który działa na urządzeniu. Zamiast tego kompiluje się w pliku Android Archive (AAR), którego można użyć jako zależności modułu aplikacji na Androida. W przeciwieństwie do plików JAR pliki AAR oferują te funkcje w aplikacjach na Androida:

  • Pliki AAR mogą zawierać zasoby Androida i plik manifestu, który pozwala łączyć w pakiecie współdzielone zasoby, takie jak układy i elementy rysowania, oraz klasy i metody Kotlin lub Java.
  • Pliki AAR mogą zawierać biblioteki C/C++, które są używane przez kod C/C++ modułu aplikacji.

Moduł biblioteki przydaje się wtedy, gdy:

  • Gdy tworzysz wiele aplikacji wykorzystujących te same komponenty, np. aktywności, usługi
  • Tworząc aplikację, która występuje w wielu wersjach plików APK, np. w wersji bezpłatnej i płatnej, ma takie same podstawowe komponenty,

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

Z tego artykułu dowiesz się, jak utworzyć moduł biblioteki Androida i go używać. Wskazówki dotyczące publikowania biblioteki znajdziesz w sekcji Publikowanie biblioteki.

Tworzenie modułu biblioteki

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

  1. Kliknij File > New > New Module (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 Dalej.

    Możesz też utworzyć bibliotekę Kotlin lub Java, która tworzy tradycyjny plik JAR. Chociaż plik JAR jest przydatny w wielu projektach, zwłaszcza gdy chcesz udostępnić kod na innych platformach, nie pozwala na umieszczenie zasobów Androida ani plików manifestu, co jest bardzo przydatne przy ponownym wykorzystywaniu kodu w projektach na Androida. Ten przewodnik skupia się na tworzeniu bibliotek Androida.

  3. Nazwij bibliotekę 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 w panelu wyświetla się widok Android.

Konwertowanie modułu aplikacji na moduł biblioteki

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

  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. Może to być zdefiniowane tylko w module aplikacji na Androida.
  3. U góry pliku znajdź blok „wtyczki”, który wygląda tak:

    Odlotowe

      plugins {
          id 'com.android.application'
      }
      

    Kotlin

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

    Zmień go na taki:

    Odlotowe

      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 jak biblioteka Androida. Zamiast pakietu APK tworzy plik AAR.

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

Dodawanie zależności w oknie Struktura projektu

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

Korzystaj z 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. Kliknij Plik > Struktura projektu > Zależności.
  2. Wybierz moduł, do którego chcesz dodać bibliotekę.
  3. Na karcie Deklarowane zależności kliknij i w 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 ona 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ść. Ma on taką postać:

Odlotowe

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

Kotlin

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

Używaj swojej biblioteki w innych projektach

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

Gdy biblioteka Androida jest opublikowana w repozytorium Maven, dołączane są metadane, dzięki czemu zależności biblioteki są uwzględniane w używającej kompilacji. Dzięki temu można automatycznie usuwać duplikaty z biblioteki, jeśli jest używana w wielu miejscach.

Aby użyć kodu z biblioteki 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 wybierz w menu 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.

    Dodaj zależność biblioteki w oknie Struktura projektu

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

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):

Odlotowe

  implementation 'com.example:examplelibrary:1.0.0'

Kotlin

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

Dodaj AAR lub JAR jako zależność

Aby użyć kodu z biblioteki na Androida 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ź 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):

    Odlotowe

      implementation files('my_path/my_lib.aar')
    

    Kotlin

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

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

Odlotowe

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 domyślnie są publiczne. Aby domyślnie ustawić wszystkie zasoby jako 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 dodajesz wcześniej zasobów publicznych, musisz utworzyć plik public.xml w katalogu res/values/ Twojej biblioteki.

Ten przykładowy kod tworzy 2 publiczne zasoby ciągu znaków 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 automatycznego prywatnego oznaczania zasobów, zadeklarując co najmniej 1 zasób publiczny. Możesz też ustawić wszystkie zasoby jako prywatne, dodając pusty tag <public />. Nie oznacza to niczego jako publicznego, a wszystkie zasoby są prywatne.

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

Niejawne ustawienie atrybutów jako prywatnych uniemożliwia użytkownikom Twojej biblioteki otrzymywanie sugestii uzupełnienia kodu z zasobów wewnętrznej biblioteki oraz pozwala użytkownikom zmieniać nazwy zasobów prywatnych i usuwać je bez zakłócania działania klientów w bibliotece. Zasoby prywatne są odfiltrowywane z kompletnego 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 publiczne definicje zasobów i wyodrębnia je do pliku public.txt, który jest następnie spakowany w pliku AAR.

Uwagi na temat programowania modułów biblioteki

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

  • Biblioteki są scalane w kolejności według priorytetu.

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

  • Unikaj konfliktów podczas scalania zasobów.

    Narzędzia do kompilacji scalają zasoby z modułu biblioteki z zasobami modułu zależnych aplikacji. Jeśli dany identyfikator zasobu jest zdefiniowany w obu modułach, używany jest 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żej początku bloku dependencies).

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

  • W kompilacjach złożonych z wielu modułów zależności JAR są traktowane jako zależności pośrednie.

    Gdy dodasz zależność JAR do projektu biblioteki, który zwraca plik AAR, plik JAR jest przetwarzany przez moduł biblioteki i spakowany z jego pakietem AAR.

    Jeśli jednak projekt zawiera moduł biblioteki, który jest wykorzystywany przez moduł aplikacji, traktuje on lokalną zależność pliku 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 kompilacje przyrostowe spowodowane zmianami kodu biblioteki.

    Wszystkie konflikty zasobów Java 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 tym przypadku moduł zależny musi opierać się na elemencie docelowym, 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 przez bibliotekę lub od niej większa.

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

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

    Podczas tworzenia zależnych modułów aplikacji moduły biblioteki są skompilowane w plik AAR, a następnie dodawane do modułu aplikacji. Dlatego każda biblioteka ma własną klasę R, nazywaną zgodnie z nazwą pakietu biblioteki.

    Klasa R wygenerowana na podstawie 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 kompilowania i publikowania aplikacji AAR, możesz dodać do konfiguracji kompilacji biblioteki plik konfiguracji ProGuard. Jeśli to zrobisz, wtyczka Androida do obsługi Gradle będzie stosować 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, plik ProGuard biblioteki jest dołączany do pliku konfiguracyjnego ProGuard (proguard.txt) modułu aplikacji.

    Umieszczając plik ProGuard w module biblioteki, zyskujesz pewność, że moduły aplikacji, które zależą od Twojej biblioteki, nie będą musiały ręcznie aktualizować swoich plików ProGuard, aby korzystać z Twojej biblioteki. Podczas tworzenia aplikacji system kompilacji Android Studio używa dyrektyw z modułu aplikacji i biblioteki. Nie trzeba więc w osobnym kroku uruchamiać w bibliotece narzędzia do skracania kodu.

    Aby dodać reguły ProGuard do projektu biblioteki, podaj 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:

    Odlotowe

    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ę w postaci pliku APK i nie generuje AAR, zmniejszaj kod tylko w module aplikacji, który zużywa bibliotekę. Więcej informacji o regułach ProGuard i ich wykorzystaniu znajdziesz w artykule o zmniejszaniu, zaciemnianiu i optymalizowaniu aplikacji.

  • Testowanie modułu biblioteki przypomina 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 plik APK zawiera nie tylko własny kod, ale też plik AAR biblioteki i wszystkie jego zależności. Ponieważ w trakcie testowania nie ma osobnej aplikacji, zadanie androidTest instaluje (i odinstaluje) tylko testowy plik APK.

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

Składnia pliku AAR

Plik AAR ma rozszerzenie .aar, a typ artefaktu Maven to też aar. Sam plik jest plikiem ZIP. Jedyny wymagany wpis to /AndroidManifest.xml.

Plik AAR może też zawierać co najmniej 1 z tych pozycji opcjonalnych: