Tworzenie wielu plików APK dla różnych poziomów interfejsu API

Jeśli publikujesz aplikację w Google Play, musisz utworzyć i przesłać pakiet Android App Bundle. Gdy to zrobisz, Google Play będzie automatycznie generować i udostępniać zoptymalizowane pliki APK dla każdej konfiguracji urządzenia. Dzięki temu użytkownicy pobierają tylko kod i zasoby niezbędne do uruchomienia Twojej aplikacji. Publikowanie wielu plików APK jest przydatne, jeśli nie publikujesz w Google Play, ale musisz samodzielnie stworzyć i podpisać każdy plik APK oraz nim zarządzać.

Przy tworzeniu aplikacji na Androida, która ma korzystać z wielu pakietów APK dostępnych w Google Play, warto stosować sprawdzone metody od samego początku i uniknąć niepotrzebnych problemów w trakcie procesu programowania. Z tej lekcji dowiesz się, jak utworzyć wiele plików APK aplikacji, z których każdy obejmuje nieco inny zakres poziomów API. Zyskasz też dostęp do narzędzi, które sprawią, że obsługa bazy kodu z wieloma plikami APK będzie jak najbardziej prosta.

Potwierdzanie, że potrzebujesz wielu plików APK

Gdy próbujesz utworzyć aplikację, która działa na wielu generacjach platformy Androida, oczywiście zależy Ci na korzystaniu z nowych funkcji na nowych urządzeniach bez negatywnego wpływu na zgodność wsteczną. Na początku może się wydawać, że najlepszym rozwiązaniem będzie obsługa wielu plików APK, ale w większości przypadków nie jest to regułą. W sekcji Korzystanie z pojedynczego pliku APK w przewodniku dla programistów dla programistów tworzących wiele plików APK znajdziesz przydatne informacje o tym, jak można to zrobić za pomocą pojedynczego pliku APK oraz jak korzystać z naszej biblioteki pomocy. Z tego artykułu możesz się też dowiedzieć, jak pisać w jednym pliku APK kod, który działa tylko na określonych poziomach interfejsu API, bez konieczności korzystania z kosztownych metod obliczeniowych.

Jeśli możesz nią zarządzać, ograniczenie aplikacji do jednego pliku APK ma kilka zalet, w tym:

  • Publikowanie i testowanie jest łatwiejsze
  • Trzeba zarządzać tylko jedną bazą kodu.
  • Aplikacja może dostosowywać się do zmian konfiguracji urządzenia.
  • Przywracanie aplikacji z różnych urządzeń po prostu działa
  • Nie musisz martwić się o preferencje rynkowe, zachowanie użytkowników od momentu przejścia z jednego pakietu APK na kolejny ani który plik APK pasuje do danej klasy urządzeń.

W pozostałej części tej lekcji zakładamy, że znasz już temat, dokładnie wiesz, co znajduje się w powiązanych z nimi zasobach, i że stwierdzisz, że wiele plików APK to odpowiednia ścieżka dla Twojej aplikacji.

Pokaż swoje wymagania

Zacznij od utworzenia prostego wykresu, aby szybko określić, ile plików APK potrzebujesz i jaki zakres interfejsów API obejmuje każdy z nich. Więcej informacji można znaleźć na stronie Wersje platformy w witrynie dla deweloperów aplikacji na Androida, która zawiera dane o względnej liczbie aktywnych urządzeń, na których działa dana wersja platformy Androida. Choć na początku wydaje się to łatwe, śledzenie, na który zestaw poziomów API będzie kierowany każdy plik APK, staje się trudniejsze, zwłaszcza gdy zakresy tych poziomów się pokrywają (często się zdarza). Na szczęście możesz szybko i łatwo opracować swoje wymagania oraz mieć do nich łatwy dostęp później.

Aby utworzyć wykres z wieloma plikami APK, zacznij od wiersza komórek reprezentujących różne poziomy interfejsu API platformy Androida. Dodaj na końcu dodatkową komórkę, która symbolizuje przyszłe wersje Androida.

3 4 5 6 7 8 9 10 11 12 13 +

Teraz wystarczy pokolorować wykres, aby każdy kolor odpowiadał pakietowi APK. Oto przykład zastosowania każdego pliku APK do określonych poziomów interfejsu API.

3 4 5 6 7 8 9 10 11 12 13 +

Po utworzeniu tego wykresu przekaż go swojemu zespołowi. Komunikacja między zespołem w projekcie stała się od razu prostsza – zamiast pytać: „Jak jest z interfejsem API na poziomach od 3 do 6?”, czyli na Androida 1.x? Co Ty na to?”. Możesz po prostu powiedzieć „Co z niebieskim pakietem APK?”.

Umieść cały wspólny kod i zasoby w projekcie biblioteki

Niezależnie od tego, czy modyfikujesz istniejącą aplikację na Androida, czy tworzysz ją od podstaw, jest to pierwsza i najważniejsza rzecz, którą należy zrobić w kodzie bazy kodu. Wszystko, co wchodzi w projekt biblioteki, trzeba zaktualizować tylko raz (np. tłumaczone teksty, motywy kolorystyczne, poprawki błędów we wspólnym kodzie), co skraca czas tworzenia aplikacji i zmniejsza ryzyko popełnienia pomyłek, których można było łatwo uniknąć.

Uwaga: chociaż szczegóły implementacji tworzenia i dołączania projektów bibliotecznych wykraczają poza zakres tej lekcji, aby dowiedzieć się więcej, przeczytaj artykuł Tworzenie biblioteki na Androida.

Jeśli konwertujesz istniejącą aplikację do obsługi wielu plików APK, przeszukaj bazę kodu w poszukiwaniu każdego zlokalizowanego pliku ciągu znaków, listy wartości, kolorów motywów, ikon menu i układu, które nie będą się zmieniać w różnych plikach APK, i umieść wszystko w projekcie biblioteki. Kod, który się nie zmieni, powinien trafić również do projektu bibliotecznego. Prawdopodobnie rozszerzysz te klasy, aby dodać metodę lub dwie metody z pliku APK do pliku APK.

Jeśli jednak tworzysz aplikację od podstaw, najpierw spróbuj napisać jak najwięcej kodu w projekcie bibliotecznym, a potem w razie potrzeby przenieś ją do pojedynczego pliku APK. W dłuższej perspektywie łatwiej jest zarządzać tym obiektem niż dodawać go do jednego, potem kolejnego, a potem kolejnego, a potem wielu miesięcy, próbując ustalić, czy ten obiekt blob można przenieść do sekcji biblioteki bez pomyłki.

Tworzenie nowych projektów APK

Każdy plik APK, który zamierzasz opublikować, powinien istnieć oddzielny projekt na Androida. Aby ułatwić porządkowanie, umieść projekt biblioteki i wszystkie powiązane projekty APK w tym samym folderze nadrzędnym. Pamiętaj też, że każdy plik APK musi mieć tę samą nazwę pakietu, ale niekoniecznie musi to być nazwa, która musi dzielić się z biblioteką. Jeśli masz 3 pliki APK zgodne ze schematem opisanym wcześniej, katalog główny może wyglądać tak:

alexlucas:~/code/multi-apks-root$ ls
foo-blue
foo-green
foo-lib
foo-red

Po utworzeniu projektów dodaj projekt biblioteki jako odwołanie do każdego projektu APK. Jeśli to możliwe, zdefiniuj początkową aktywność w projekcie biblioteki i rozszerz ją w projekcie APK. Dzięki zdefiniowaniu działania początkowego w projekcie biblioteki możesz umieścić wszystkie inicjowanie aplikacji w jednym miejscu, dzięki czemu nie musisz ponownie wdrażać „uniwersalnych” zadań, takich jak inicjowanie Analytics, sprawdzanie licencji czy inne procedury inicjowania, które nie zmieniają się znacznie z pakietu APK na plik APK.

Dostosowywanie plików manifestu

Gdy użytkownik pobiera z Google Play aplikację, która korzysta z wielu plików APK, właściwy plik APK jest wybierany na podstawie 2 prostych reguł:

  • Plik manifestu musi wskazywać, że dany plik APK spełnia wymagania.
  • Spośród kwalifikujących się plików APK wygrana jest największa liczba wersji

Weźmy na przykład zbiór wielu plików APK opisanych wcześniej i załóżmy, że nie ustawiliśmy maksymalnego poziomu interfejsu API dla żadnego z plików APK. Przy analizowaniu pojedynczych plików możliwy zakres każdego pliku APK wyglądałby tak:

3 4 5 6 7 8 9 10 11 12 13 +
3 4 5 6 7 8 9 10 11 12 13 +
3 4 5 6 7 8 9 10 11 12 13 +

Ponieważ pakiet APK o wyższej wartości minSdkVersion musi też mieć wyższy kod wersji, wiemy, że w przypadku wartości parametru versionCode czerwony ≥ zielony ≥ niebieski. Możemy więc skutecznie zwinąć wykres do następującej postaci:

3 4 5 6 7 8 9 10 11 12 13 +

Przyjmijmy teraz, że czerwony plik APK ma pewne wymagania, których nie ma w pozostałych. Listę możliwych przyczyn znajdziesz na stronie Filtry w Google Play w przewodniku dla programistów aplikacji na Androida. Załóżmy na przykład, że kolor czerwony wymaga przedniego aparatu. Głównym elementem czerwonego pakietu APK jest połączenie przedniego aparatu z nowymi, nowymi funkcjami, które zostały dodane w interfejsie API 11. Okazuje się jednak, że nie wszystkie urządzenia obsługujące API 11 mają nawet aparat przedni. Strach!

Na szczęście, jeśli użytkownik przegląda Google Play na takim urządzeniu, Google Play sprawdzi plik manifestu, zauważy, że czerwony wskazuje, że przedni aparat jest wymagany, i zignoruje go, bo stwierdził, że czerwony i to urządzenie nie są dokładnie takie same jak w cyfrowym niebie. Zauważy, że kolor zielony jest nie tylko zgodny z urządzeniami z interfejsem API 11 (ponieważ nie określono parametru maxSdkVersion), ale też nie ma znaczenia, czy jest przedni aparat. Użytkownik nadal może pobrać aplikację z Google Play, ponieważ pomimo całego błędu z przednim aparatem nadal dostępny był plik APK obsługiwany przez ten konkretny poziom interfejsu API.

Aby przechowywać wszystkie pliki APK na osobnych „ścieżkach”, musisz mieć dobry schemat kodu wersji. Zalecane kody znajdziesz w sekcji Kody wersji naszego przewodnika dla programistów. Ponieważ przykładowy zestaw plików APK obejmuje tylko 1 z 3 możliwych wymiarów, wystarczy rozdzielić każdy z nich liczbą 1000, ustawić kilka pierwszych cyfr na wartość minSdkVersion na potrzeby konkretnego pliku APK i zwiększyć wartość później. Może to wyglądać tak:

Niebieski: 03001, 03002, 03003, 03004...
Zielony: 07001, 07002, 07003, 07004...
Czerwony:11001, 11002, 11003, 11004...

Po połączeniu wszystkich tych elementów Twój plik manifestu Androida wyglądałby prawdopodobnie mniej więcej tak:

Niebieski:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    android:versionCode="03001" android:versionName="1.0" package="com.example.foo">
    <uses-sdk android:minSdkVersion="3" />
    ...

Zielony:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    android:versionCode="07001" android:versionName="1.0" package="com.example.foo">
    <uses-sdk android:minSdkVersion="7" />
    ...

Czerwony:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    android:versionCode="11001" android:versionName="1.0" package="com.example.foo">
    <uses-sdk android:minSdkVersion="11" />
    ...

Przejrzyj listę kontrolną przed opublikowaniem

Zanim prześlesz pliki do Google Play, dokładnie sprawdź te elementy. Pamiętaj, że dotyczą one w szczególności wielu plików APK i nie stanowią pełnej listy kontrolnej dla wszystkich aplikacji przesyłanych do Google Play.

  • Wszystkie pliki APK muszą mieć taką samą nazwę pakietu
  • Wszystkie pliki APK muszą być podpisane za pomocą tego samego certyfikatu
  • Jeśli pliki APK pokrywają się w wersjach platformy, plik z wyższą wartością minSdkVersion musi mieć wyższy kod wersji
  • Dokładnie sprawdź filtry pliku manifestu pod kątem sprzecznych informacji (plik APK, który obsługuje tylko babeczki na ekranach XLARGE, nikt nie zobaczy tego pliku).
  • Każdy plik manifestu pakietu APK musi być unikalny na co najmniej 1 obsługiwanym ekranie, teksturze OpenGL lub wersji platformy.
  • Przetestuj każdy plik APK na co najmniej jednym urządzeniu. Poza tym na Twoim komputerze znajduje się jeden z najbardziej spersonalizowanych emulatorów urządzeń w branży. Do szaleństwa!

Warto też sprawdzić skompilowany plik APK przed wprowadzeniem go na rynek, aby mieć pewność, że nie ma niespodzianek, które mogłyby ukryć aplikację w Google Play. To dość proste przy użyciu narzędzia „aapt”. Aapt (Android Asset Packaging Tool) jest częścią procesu tworzenia i pakowania aplikacji na Androida. Jest też bardzo przydatnym narzędziem do ich sprawdzania.

>aapt dump badging
package: name='com.example.hello' versionCode='1' versionName='1.0'
sdkVersion:'11'
uses-permission:'android.permission.SEND_SMS'
application-label:'Hello'
application-icon-120:'res/drawable-ldpi/icon.png'
application-icon-160:'res/drawable-mdpi/icon.png'
application-icon-240:'res/drawable-hdpi/icon.png'
application: label='Hello' icon='res/drawable-mdpi/icon.png'
launchable-activity: name='com.example.hello.HelloActivity'  label='Hello' icon=''
uses-feature:'android.hardware.telephony'
uses-feature:'android.hardware.touchscreen'
main
supports-screens: 'small' 'normal' 'large' 'xlarge'
supports-any-density: 'true'
locales: '--_--'
densities: '120' '160' '240'

Podczas analizowania danych wyjściowych aapt sprawdź, czy nie ma sprzecznych wartości dla atrybutów „supports-screen” i „zgodności” oraz czy nie zostały dodane niezamierzone wartości „uses-feature” w wyniku uprawnień ustawionych w pliku manifestu. W powyższym przykładzie plik APK nie będzie widoczny na wielu urządzeniach.

Dlaczego? Dzięki dodaniu wymaganego uprawnienia SEND_SMS automatycznie dodaliśmy wymaganie funkcji android.hardware.telephony. Interfejs API 11 to Honeycomb (wersja Androida zoptymalizowana pod kątem tabletów) i żadne urządzenia z Honeycomb nie są wyposażone w sprzęt telefoniczny, dlatego Google Play będzie odfiltrowywać ten plik APK we wszystkich przypadkach, dopóki przyszłe urządzenia nie będą miały wyższego poziomu API ORAZ będą posiadały sprzęt telefoniczny.

Na szczęście ten problem można łatwo rozwiązać, dodając do pliku manifestu te wiersze:

<uses-feature android:name="android.hardware.telephony" android:required="false" />

Domyślnie dodawany jest też wymóg android.hardware.touchscreen. Jeśli chcesz, aby pakiet APK był widoczny na telewizorach nieobsługujących ekranu dotykowego, dodaj do pliku manifestu:

<uses-feature android:name="android.hardware.touchscreen" android:required="false" />

Gdy wykonasz czynności z listy kontrolnej przed opublikowaniem, prześlij swoje pakiety APK do Google Play. Może minąć trochę czasu, zanim aplikacja pojawi się podczas przeglądania Google Play, ale gdy już się pojawi, sprawdź jeszcze raz. Pobierz aplikację na wszystkie posiadane urządzenia testowe, aby upewnić się, że pliki APK są kierowane na konkretne urządzenia. Gratulacje, to już wszystko!