2012-05-13 11 views
14

Pracuję nad projektem Open-source. Ponieważ jest to zamierzone, że każdy może pobrać źródło i zbudować je samodzielnie, nie chcę na sztywno zakodować nazwy paczki gdziekolwiek: - włączając w to strukturę katalogów.Android - Jak dynamicznie ustawić nazwę pakietu w czasie kompilacji dla projektu Open-source?

Używam budynku ant. Podobno mogę zmodyfikować build.xml, ale uważam, że jest to nadpisane przez android update. Cokolwiek zostanie użyte, zostanie przeznaczone na repozytorium Git i nie powinno być zbyt skomplikowane.

Obecnie proces budowania kodu bezpośrednio z repozytorium Git jest dość prosty. Oto fragment z pliku README:

$ cd ~/src/isokeys/IsoKeys 
$ android list targets # I build against API level 10. 
$ android update project --name IsoKeys --target 1 --path ./ # Only needed first time. 
$ ant debug && adb -d install -r bin/IsoKeys-debug.apk 

Dla mnie ma to sens, aby umieścić nazwę pakietu w local.properties, bo to jest .gitignore „d. Ponieważ nazwa pakietu nie będzie nigdzie indziej, kompilacja nie powiedzie się bez tego. Tak więc musi być co najmniej 1 dodatkowy krok w README, ale chcę go ograniczyć do minimum.

Edycja: Oczywiście innym wymaganiem jest to, że różnice mają sens - a nie, jeśli ręcznie zmienisz nazwę pakietu.

+0

Wydaje się to dość głupie. Nie słyszałem o żadnym projekcie open-source przeskakującym przez takie obręcze. –

+1

2 główne motywy to to, że różnice w katalogu o zmienionej nazwie są uciążliwe i że ten i wiele innych projektów Open-Source nie ma własnej domeny, ale raczej są hostowane na stronie kodu, takiej jak sourceforge.net, itp. a widły/łączenia są powszechne. –

Odpowiedz

20

Zrobiłem coś podobnego (ale nie z tego powodu), co wymagało zaktualizowania manifestu w czasie kompilacji. Osiągnąłem to, robiąc drugi AndroidManifest i umieszczając go w katalogu o nazwie config. Więc w config/AndroidManifest można mieć coś takiego:

<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
     package="@[email protected]" 
     android:versionCode="@[email protected]" 
     android:versionName="@[email protected]"> 


<!-- EVERYTHING ELSE GOES HERE --> 


</manifest> 

Następnie można użyć regularnych szkielety build.xml mrówek skryptu z zaledwie kilku modyfikacjach (nie ma potrzeby, aby skopiować cały skrypt z Android kompilacji system, ponieważ dodali kilka haczyków do użycia bez ponownego odkrywania koła). Skrypt build należy czytać local.properties domyślnie, ale jeśli nie dodać (lub komentarza) wiersz tak:

<property file="local.properties" /> 

W skrypcie kompilacji powinieneś zobaczyć zadanie o nazwie „-pre-build” zmień go tak:

<target name="-pre-build"> 
    <copy file="config/AndroidManifest.xml" todir="." overwrite="true" encoding="utf-8"> 
     <filterset> 
      <filter token="CONFIG.APP_PACKAGE_NAME" value="${app.packagename}" /> 
      <filter token="CONFIG.APP_VERSION" value="${app.version}" /> 
      <filter token="CONFIG.APP_VERSION_CODE" value="${app.versioncode}" /> 
     </filterset> 
    </copy>   
</target> 

Zmodyfikowane local.properties plik będzie można umieścić nazwę pakietu, wersję Nazwa/kod tak:

app.version=1.0 
app.versioncode=1 
app.packagename=com.mypackage.name 

teraz wystarczy, aby upewnić się w y nasz manifest, że w pełni kwalifikujesz wszystkie swoje działania/usługi/rozgłaszanie słuchaczy itp. Oznacza to, że zawsze określasz pełny pakiet swojego kodu źródłowego. Jeśli chcesz, aby pakiet dla twojego własnego kodu źródłowego był dynamiczny, możesz zamienić każdy prefiks na każdą klasę. Ale wydaje się to trochę głupie. Łatwo jest spakować kod pod własną nazwą pakietu i może używać go z dowolnego projektu, po prostu włączając źródło lub słoik w ich projekcie.

- AKTUALIZACJA - Aha i jeszcze jedno można zrobić, aby powiadomić użytkownika, że ​​muszą określić nazwę pakietu jest użyć tagu niepowodzenie w swojej kompilacji xml tak:

<fail message="app.packagename is missing. This must be defined in your local.properties file" unless="app.packagename" /> 

Put to po linii, która czyta lokalny.plik właściwości

+0

Ah, mój skrypt budujący (generowany przez aktualizację Androida), _is_ 'barebones' i zawiera ''. Mogę więc przekazać ten plik do repo z pewnymi modyfikacjami. Racja, niech zobaczę ... –

+0

Tak, niektórzy ludzie mówią, że to zły pomysł, ale robię to już ponad rok bez żadnych problemów. Najwyraźniej zostawiają wam te haki, ale nie ma żadnej gwarancji, że w następnej wersji androida mogliby coś zmienić. IIRC drugą rzeczą, którą musiałem zrobić, aby grał ładnie z Eclipse, było dodanie: Jednak dla powyższe zmiany nie powinny tego wymagać. Potrzebowałem go tylko po to, abym mógł ponownie użyć niektórych celów w pliku tools/ant/build.xml z mojego skryptu, a do tego musiałbym po prostu użyć androidbuild. [Nazwa_celu] –

+0

Gdybym nie miał Sekcja "as = androidbuild", a następnie zaćmienie narzekałoby na to, że cele nie istniały, a zaćmienie nie zdołałoby zbudować mojego projektu, mimo że w ogóle nie używałem skryptu mrówki z zaćmienia. –

6

Z podziękowaniami dla Matta Wolfe'a za jego pomoc, częściowo opowiadam o swoich dotychczasowych wysiłkach.

Zauważyłem, że domyślna Barebone build.xml również importować custom_rules.xml:

<import file="custom_rules.xml" optional="true" /> 

Więc stworzyłem ten plik i zaczął majstrować. To, co mam wymyślić do tej pory:

<?xml version="1.0" encoding="UTF-8"?> 
<project name="custom_rules" default="debug"> 
    <target name="-pre-build"> 
     <fail message="Please define app.packagename in your local.properties file." unless="app.packagename" /> 
     <taskdef resource="net/sf/antcontrib/antcontrib.properties"> 
      <classpath> 
       <pathelement location="/usr/share/java/ant-contrib.jar"/> 
      </classpath> 
     </taskdef> 
     <!-- How do I check for propertyregex? 
     <fail message="Depends on ant-contrib's propertyregex for app.packagename.path." unless="propertyregex" /> 
     --> 
     <propertyregex property="app.packagename.path" 
      input="${app.packagename}/" 
      regexp="\." 
      replace="/" 
      global="true" 
     /> 
     <copy todir="build/" overwrite="true" encoding="utf-8"> 
      <fileset dir="./"> 
       <include name="AndroidManifest.xml" /> 
       <include name="res/**" /> 
       <include name="lib/**" /> 
      </fileset> 
      <filterset> 
       <filter token="CONFIG.APP_PACKAGE_NAME" value="${app.packagename}" /> 
      </filterset> 
     </copy> 
     <copy todir="build/src/${app.packagename.path}" overwrite="true" encoding="utf-8"> 
      <fileset dir="./src/isokeys/"> 
       <include name="**" /> 
      </fileset> 
      <filterset> 
       <filter token="CONFIG.APP_PACKAGE_NAME" value="${app.packagename}" /> 
      </filterset> 
     </copy> 
    </target> 
    <target name="-pre-clean" description="Removes output files created by -pre-build."> 
     <delete file="build/AndroidManifest.xml" verbose="${verbose}" /> 
     <delete dir="build/res/" verbose="${verbose}" /> 
     <delete dir="build/lib/" verbose="${verbose}" /> 
     <delete dir="build/src/" verbose="${verbose}" /> 
    </target> 
    <!-- NOW CHANGE DIRECTORY TO build/ BEFORE HANDING BACK OVER TO build.xml!!! --> 
</project> 

ten ustawia wszystko w build/(który ma dodatkowy bonus utrzymanie rzeczy uporządkowane), teraz intencją jest dla narzędzi SDK build.xml do uruchom z tego katalogu build/. Jednak nie mogę znaleźć żadnego sposobu.

+0

Do tej pory jest tylko jeden dodatkowy krok dla 'README', który jest dobrą wiadomością:' $ echo 'app.packagename = your.package.name' >> local.properties' –

+0

Polecam dodanie tego na końcu, jak byłem uzyskanie błędu w pliku XML budowy. Dzieje się tak, ponieważ zadanie Androida wymaga elementu , podczas gdy zadanie ant-contrib, jeśli nie obsługuje go. Ponieważ nie możemy zmienić plików kompilacji Androida i musimy ich przestrzegać, jesteśmy zmuszeni korzystać z systemu Android, jeśli zadanie jest we wszystkich miejscach: <ścieżka id = "build.android.antlibs"> <ścieżka dożużlaka = "$ {sdk.dir } /tools/lib/anttasks.jar "/> Jack

+0

jak zmienić katalog na budować/ ? – Jason

1

Najprostszym sposobem może być zastąpienie nazwy pakietu tak późno, jak to możliwe. W ten sposób nie musisz nawet dotykać kodu. Jest fajny artykuł o nazwie Renaming the Android Manifest package (http://www.piwai.info/renaming-android-manifest-package/). Podsumowanie:

  • Można użyć aapt --rename-manifest-package zmodyfikować nazwę pakietu

  • Ewentualnie, jeśli chcesz nazwę pakietu zastępstwo być częścią mrówek procesu kompilacji, można przesłonić cel -package-resources:

    • skopiować cel -package-resources z SDK build.xml
    • dodać manifestpackage parametr