2012-05-13 41 views
14

我正在開發一個開源項目。因爲任何人都可以下載源代碼並自行構建它,所以我不想在任何地方包括目錄結構對包名稱進行硬編碼。Android - 如何在構建時爲開源項目動態設置包名?

我使用ant建設。顯然我可以修改build.xml,但我相信這被android update覆蓋。無論使用什麼,都將致力於Git回購,並且它不應該太複雜。

目前,直接從Git倉庫構建代碼的過程相當簡單。下面是來自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 

對我來說,這是有道理的放包名local.properties,因爲這是.gitignore「d。由於軟件包名稱不在其他地方,因此構建將會失敗,而不會執行此操作。所以在README中至少需要一個額外的步驟,但我希望保持在最低限度。

編輯:當然,另一個要求是差異是有道理的 - 如果您手動重命名包名稱,則不會這樣做。

+0

這似乎是愚蠢的。我還沒有聽說過任何這樣的開源項目。 –

+1

的2個主要動機是爲重命名的目錄比較是一個痛苦,這和其他許多開源項目並沒有自己的域名而是在託管網站一樣sourceforge.net等代碼託管,叉子/合併是司空見慣的。 –

回答

20

我做了類似的事情(但不是因爲這個原因),它需要在構建時更新清單。我完成這個的方式是製作第二個AndroidManifest並將其放在名爲config的目錄下。 所以在配置/ AndroidManifest你可以有這樣的事情:

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

然後你可以使用常規的裸露的骨頭的build.xml Ant腳本,只需很少的修改(不需要整個腳本從Android構建複製系統,因爲他們添加了一些鉤子供您使用,而無需重新發明輪子)。 構建腳本默認情況下應閱讀local.properties,但如果不加(或去掉註釋)這樣一行:

<property file="local.properties" /> 

在構建腳本,你應該可以看到一個名爲「 - 預構建」的任務,改變這樣的:

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

然後你local.properties文件,你會放包的名稱,版本名稱/代碼如下所示:

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

現在你只需要確保沿y我們的清單表明您完全符合您的所有活動/服務/廣播聽衆等等。這意味着您始終指定完整的源代碼包。如果你想讓你自己的源代碼的包是動態的,你可以將每個前綴替換爲每個類。但是這看起來很愚蠢......很容易將代碼打包到你自己的包名下,可以在任何項目中使用它,只需在項目中包含源代碼或jar。

- 更新 - 哦,你可以做,通知他們必須定義一個包名用戶一件事是使用故障標記在構建這樣的XML:

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

將這個在讀取本地的行後。屬性文件

+0

啊,我的構建腳本(由android更新生成),_is_'barebones'幷包含''。所以我可以通過一些修改將此文件提交到回購站。對,讓我看看... –

+0

是的,有些人說這是一個壞主意,但我已經做了好一年沒有任何問題。他們顯然爲你留下了這些鉤子,但沒有任何保證,在下一個Android版本,他們可以改變的事情。 IIRC其他的事情我必須做它與Eclipse發揮好是加: 導入文件<=「$ {} sdk.dir /tools/ant/build.xml」爲=「androidbuild」 /> 然而,對於上面的更改不應該需要這個。我只需要它,這樣我可以重用的一些目標,從我的腳本工具/ ANT/build.xml文件,要做到這一點我會那麼就只好用androidbuild。[目標] –

+0

如果我沒有足夠的「as = androidbuild」部分,然後eclipse會抱怨目標不存在,並且eclipse將無法構建我的項目,即使我並沒有在eclipse中使用我的ant腳本。 –

6

與感謝馬特·沃爾夫對他的幫助,我張貼了部分答案與我的努力至今。

我注意到,默認準系統build.xml也將導入custom_rules.xml

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

所以我創造了這個文件,並開始擺弄。這就是我來了這麼遠:

<?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> 

build/完成所有設置(已保存的東西乾淨整潔的好處),現在的意圖是SDK工具build.xml到從此build/目錄運行。但是,我找不到任何方式cd'ing。

+0

到目前爲止,'README'只有一個額外的步驟,這是個好消息:'$ echo'app.packagename = your.package.name'>> local.properties' –

+0

建議在最後添加這個,因爲我是在構建xml中出現錯誤。這是因爲Android的if任務需要元素,而ant-contrib的if任務不支持它。因爲我們無法更改Android的構建文件並且必須遵守它們,所以我們被迫在所有地方使用Android的if任務 <的taskdef名稱= 「如果」 類名= 「com.android.ant.IfElseTask」 classpathref = 「build.android.antlibs」/> – Jack

+0

如何改變到目錄建立/? – Jason

1

最簡單的方法可能會被儘可能晚地更換包名。這樣,你甚至不必碰觸你的代碼。有一篇不錯的文章,名字叫Renaming the Android Manifest packagehttp://www.piwai.info/renaming-android-manifest-package/)。摘要:

  • 您可以使用aapt --rename-manifest-package修改包名

  • 另外,如果你想包的名稱更換爲Ant構建過程的一部分,您可以覆蓋-package-resources目標:

    • 複製-package-resources目標從SDK的build.xml
    • 添加manifestpackage參數
相關問題