Gradle dla Androida, AAR i uzależnienia warunkowe

Skrócona forma: Jakie są sposoby porządkowania kodu / POM dla AAR, tak że aplikacje używające tego AAR mają tylko zależności, których faktycznie potrzebują?

Długa forma:

Załóżmy, że mamy aplikację, która zależy od projektu biblioteki Android spakowanego jako AAR (L).

L zawiera mieszankę klas, a każda aplikacja (np. A) użyje tylko podzbioru tych klas. Na przykład:

L może zawieraćFragment implementacje natywnych fragmentów interfejsu API poziomu 11, fragmentów przeniesionych z powrotem i fragmentów o smaku ActionBarSherlock

L może zawieraćActivity wdrożenia do regularnych działań,FragmentActivity, ActionBarActivityoraz działania o smaku ActionBarSherlock

L może podnosić wydarzenia przezLocalBroadcastManager, Square's Otto i EventBus Greenrobota

I tak dalej

Te przypadki mają dwie główne cechy wspólne, jak to widzę:

Aplikacje zazwyczaj dotyczą tylko niektórych klas. Na przykład aplikacja korzystająca z Otto nie dba o kod, który odwołuje się do EventBus Greenrobota, lub o aplikacji, która z niego korzystaActionBarActivity nie przejmuje się ActionBarSherlock.

Jeśli AAR jest artefaktem w repozytorium, aplikacje nie będą się przejmować wszystkimi możliwymi zależnościami potrzebnymi do zbudowania AAR. Na przykład aplikacja korzystająca z natywnych fragmentów interfejsu API poziomu 11 nie będzie potrzebowaćsupport-v4 lubactionbarsherlock, chociaż sam AAR potrzebuje ich do zbudowania rocznego sprawozdania z działalności

Jeśli mielibyśmy korzystać z JAR zamiast AAR i zarządzania zrzucaniem zależności, jest to dość proste. Budowanie JAR miałoby zależności czasu kompilacji (np.support-v4). Jednak aplikacje korzystające z tego JAR mogą pominąć te zależności i dopóki aplikacje te nie używają klas, które naprawdę potrzebują tych zależności, życie jest dobre.

Mam jednak trudności z zobaczeniem, jak osiągnąć to samo z artefaktami AAR i Maven określonymi w abuild.gradle plik. Jeśli L madependencies blok odwołując się do zależności w górę, aplikacje z kolei pobierają te zależności w sposób przejściowy, gdy aplikacje zależą od L.

Jedynym rozwiązaniem, które jestem całkiem pewne, będzie podział L na kilka bibliotek. Na przykład, używając scenariusza fragmentu, możemy mieć:

L1, który zawiera implementację natywnej wersji fragmentów interfejsu API poziomu 11 oraz dowolny wspólny kod potrzebny do innych scenariuszy. Ta biblioteka nie miałaby żadnych zależności.

L2, który zawiera implementację, która korzysta z backportu fragmentów pakietu wsparcia Android. L2 miałby zależności na L1 i nasupport-v4.

L3, który zawiera implementację wykorzystującą fragmenty o smaku Sherlocka. L3 miałby zależności od L1 iactionbarsherlock.

Następnie aplikacja zdecyduje, czy zależeć będzie od L1, L2, czy L3, a zatem otrzyma tylko niezbędne zależności w górę (jeśli istnieją).

Moje pytanie brzmi: czy to najlepsze rozwiązanie? Czy jest jeszcze coś w świecie Gradle dla Androida, AAR i artefaktów w stylu Maven, które pozwalają aplikacjom polegać na pojedynczym L? Jestem zaniepokojony możliwymi kombinatorycznymi eksplozjami bibliotek, aby poradzić sobie ze zróżnicowaną mieszanką zależności zależnych. Martwię się również o dziwne aplikacjerobić potrzebują wielu wdrożeń i niezależnie od tego, czy potrafimy niezawodnie określić zależności dla tych aplikacji (np. aplikacja zależna zarówno od L1, jak i L2, ponieważ to, co autor tej aplikacji uważa za potrzebne aplikacji).

Wiem, że istnieją sposoby na aplikacjęblok wykluczać zależności (patrz odpowiedź Josepha Earla na składnię), więc aplikacja może zależeć od L, a następnie zablokowaćactionbarsherlock zależność upstream, jeśli nie jest potrzebna. Chociaż mogłoby to zadziałać, w przypadkach, w których jestem autorem L, wolałbym zastosować podejście L1 / L2 / L3, ponieważ wydaje się to czystsze.

Jakieś inne sugestie?

questionAnswers(3)

yourAnswerToTheQuestion