Tworzenie wielu plików APK dla różnych tekstur GL

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ć.

Gdy tworzysz aplikację 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 na etapie programowania. Z tej lekcji dowiesz się, jak utworzyć wiele plików APK swojej aplikacji, które obsługują inny podzbiór formatów tekstur OpenGL. Zyskasz też dostęp do narzędzi, dzięki którym 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ę działającą na wszystkich dostępnych urządzeniach z Androidem, zależy Ci oczywiście na tym, aby wyglądała ona najlepiej na każdym urządzeniu, bez względu na to, że nie wszystkie obsługują ten sam zestaw tekstur GL. Na początku może się wydawać, że obsługa wielu plików APK to najlepsze rozwiązanie, ale w wielu przypadkach tak nie jest. W sekcji Korzystanie z pojedynczego pliku APK w przewodniku dla programistów dotyczącym wielu plików APK znajdziesz przydatne informacje o tym, jak można to osiągnąć za pomocą pojedynczego pliku APK, m.in. jak wykrywać obsługiwane formaty tekstur w czasie działania. W zależności od sytuacji być może łatwiej będzie połączyć wszystkie formaty z aplikacją i po prostu wybrać, którego z nich chcesz używać w czasie działania.

Jeśli możesz nim 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

Przewodnik dla programistów aplikacji na Androida zawiera przydatne informacje o niektórych typowych obsługiwanych teksturach na stronie supports-gl-texture. Na tej stronie znajdują się również wskazówki dotyczące tego, które telefony (lub rodziny telefonów) obsługują poszczególne formaty tekstur. Pamiętaj, że zwykle dobrze jest, aby jeden z plików APK obsługiwał EETC1, ponieważ ten format tekstury jest obsługiwany przez wszystkie urządzenia z Androidem, które obsługują specyfikację OpenGL ES 2.0.

Większość urządzeń z Androidem obsługuje więcej niż jeden format tekstur, więc musisz określić kolejność preferencji. Utwórz wykres zawierający wszystkie formaty obsługiwane przez Twoją aplikację. Komórka znajdująca się skrajnie od lewej będzie miała najniższy priorytet (prawdopodobnie będzie to ETC1, co jest bardzo dobrym ustawieniem domyślnym pod względem wydajności i zgodności). Następnie pokoloruj wykres, aby każda komórka odpowiadała pakietowi APK.

ETC1 ATI Tryb PowerVR

Kolorowanie na wykresie nie tylko sprawia, że przewodnik jest mniej monochromatyczny, lecz także ułatwia komunikację w obrębie zespołu. Teraz każdy plik APK możesz określić jako „niebieski”, „zielony” lub „czerwony” zamiast „Ten, który obsługuje formaty tekstur ETC1” itp.

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, jest wybierany odpowiedni plik na podstawie kilku prostych zasad:

  • 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
  • Jeśli urządzenie na rynku obsługuje którekolwiek z formatów tekstur wymienionych w Twoim pliku APK, uznaje się je za odpowiednie.

Jeśli chodzi o tekstury GL, ta ostatnia reguła jest ważna. Oznacza to na przykład, że musisz zachować bardzo ostrożność przy korzystaniu z różnych formatów GL w tej samej aplikacji. Gdyby system PowerVR był używany przez 99% przypadków, a ETC1 – np. jako ekran powitalny... Plik manifestu musi zawierać obsługę obu formatów. Urządzenie, które obsługuje tylko ETC1, zostanie uznane za zgodne, aplikacja zostanie pobrana, a użytkownik zobaczy ekscytujące komunikaty o awariach. Częstym przypadkiem jest to, że jeśli używasz wielu plików APK do kierowania na różne urządzenia z zastosowaniem obsługi tekstur GL, dla każdego pliku APK przypada jeden format tekstury.

Dlatego obsługa tekstur różni się nieco od obsługi 2 wielu wymiarów plików APK, poziomu interfejsu API i rozmiaru ekranu. Każde urządzenie ma tylko 1 poziom interfejsu API i 1 rozmiar ekranu, a ich zakres obsługi zależy od pliku APK. Jeśli używasz tekstur, pakiet APK obsługuje zwykle jedną teksturę, a urządzenie obsługuje wiele. Jedno urządzenie obsługujące wiele plików APK często się pokrywa, ale rozwiązanie jest to samo: kody wersji.

Weźmy na przykład kilka urządzeń i sprawdź, ile określonych wcześniej plików APK pasuje na każde z nich.

FooPhone Nexus S Ewo
ETC1 ETC1 ETC1
Tryb PowerVR ATI TC

Zakładając, że formaty PowerVR i ATI są preferowane zamiast ETC1 (jeśli są dostępne) – zgodnie z regułą „najwyższy numer wersji wygrywa”. Jeśli w każdym pliku APK ustawisz atrybut versionCode w taki sposób, że czerwony ≥ zielony ≥ niebieski, na urządzeniach, które je obsługują, kolorem czerwonym i niebieskim będą zawsze wybierany czerwony i zielony. Gdy urządzenie, które kiedykolwiek je obsługuje, zostanie wybrany kolor czerwony.

Aby przechowywać wszystkie pliki APK na osobnych „ścieżkach”, musisz mieć dobry schemat kodu wersji. Zalecane kody można znaleźć w sekcji Kody wersji naszego przewodnika dla programistów. Przykładowy zestaw plików APK obejmuje tylko jeden z 3 możliwych wymiarów, więc wystarczy oddzielić każdy z nich po 1000, a potem zwiększyć jego wartość. Może to wyglądać tak:

Niebieski: 1001, 1002, 1003, 1004...
Zielony: 2001, 2002, 2003, 2004...
Czerwony:3001, 3002, 3003, 3004...

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

Niebieski:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    android:versionCode="1001" android:versionName="1.0" package="com.example.foo">
    <supports-gl-texture android:name="GL_OES_compressed_ETC1_RGB8_texture" />
    ...

Zielony:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    android:versionCode="2001" android:versionName="1.0" package="com.example.foo">
    <supports-gl-texture android:name="GL_AMD_compressed_ATC_texture" />
    ...

Czerwony:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    android:versionCode="3001" android:versionName="1.0" package="com.example.foo">
    <supports-gl-texture android:name="GL_IMG_texture_compression_pvrtc" />
    ...

Przejrzyj listę kontrolną przed opublikowaniem

Zanim prześlesz pliki do Google Play, dokładnie sprawdź te elementy. Pamiętaj, że odnoszą się one do 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
  • 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 pliku 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 masz jeden z najbardziej dostępnych emulatorów urządzeń w branży, który jest dostępny na Twoim komputerze. 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: '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 przykładzie powyżej plik APK będzie niewidoczny dla większości lub na wszystkich urządzeniach.

Dlaczego? Dzięki dodaniu wymaganego uprawnienia SEND_SMS automatycznie dodaliśmy wymaganie funkcji android.hardware.telephony. Większość bardzo dużych urządzeń (o ile nie wszystkie) to tablety bez sprzętu telefonicznego, dlatego Google Play odfiltruje w takich przypadkach ten plik APK, dopóki nie pojawią się urządzenia, które będą na tyle duże, że mogą być traktowane jako duży ekran, i będą zawierać 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 ewentualne urządzenia testowe, aby upewnić się, że pliki APK są kierowane na konkretne urządzenia. Gratulacje, to już wszystko!