如何將Android應用程式編譯至image/rom中

來源:互聯網
上載者:User

http://blog.csdn.net/silvervi/article/details/6315606

有時我們希望將自己的Android應用程式編譯至image/rom中,這樣程式將被安裝至/system/app目錄下,並且不能被卸載。下面
我以自己的程式TestJniApp為例子,仿照原始碼中內建的SimpleJNI,示範一下怎樣將自己的應用程式編譯至rom中。

1.    搭建編譯環境

編譯環境: Ubuntu 10.10
Android版本:Android 2.2

編譯過程中可能需要在Ubuntu上安裝必要的一些軟體,我安裝過的包含如下軟體,不同的系統可能會有差別:
jdk6(Android官方建議裝jdk5,但是我在編譯時間會遇到Java override問題,改用6沒有任何問題), bison, lib64z1-dev, libasound2-dev, flex, gperf, libncurses5-dev

2.    應用程式存放目錄

      SimpleJNI是採用Android NDK和Java編寫的程式,包含apk和so庫檔案,它的原始碼在source tree的development/samples/目錄下。
      實際上package在編譯時間所放的目錄並沒有明確限定,編譯後apk和so存放的位置是根據目錄下Android.mk所指定的編譯類型所決定的,例如:

  • SimpleJNI根目錄下的Android.mk中有一行include $(BUILD_PACKAGE),表示將該目錄下的模組編譯成package,即apk檔案,預設存放的位置為/system/app。
  • SimpleJNI/jni目錄下的Android.mk中有一行為include $(BUILD_SHARED_LIBRARY),表示將該目錄下的native.cpp編譯為共用庫檔案,即so檔案,預設存放的位置為/system/lib

      因此,如果我們想要將自己編寫的程式編譯至image中,只需要將Eclipse下完成的整個工程copy到source tree下的某個目錄即可,我一般習慣放到packages/apps下。

3.    添加Android.mk

完成了上一步,可以知道,Android.mk在編譯中起著至關重要的作用,這其實就是Android編譯環境中的make
file。為了完成我們的工作,需要在原始碼中添加Android.mk。添加自己的Android.mk可以仿照SimpleJNI中的
Android.mk,稍微修改即可。我們首先看看SimpleJNI目錄下的兩個Android.mk的內容:


  • 目錄下的Android.mk

TOP_LOCAL_PATH:= $(call my-dir)

# Build activity

LOCAL_PATH:= $(TOP_LOCAL_PATH)
include $(CLEAR_VARS)

LOCAL_MODULE_TAGS := samples

LOCAL_SRC_FILES := $(call all-subdir-java-files)

LOCAL_PACKAGE_NAME := SimpleJNI

LOCAL_JNI_SHARED_LIBRARIES := libsimplejni

LOCAL_PROGUARD_ENABLED := disabled

include $(BUILD_PACKAGE)

# ============================================================

# Also build all of the sub-targets under this one: the shared library.
include $(call all-makefiles-under,$(LOCAL_PATH))

      根目錄下的Android.mk決定了整個工程編譯的配置,其中,

      LOCAL_PATH 定義了當前的目錄

      LOCAL_MUDULE_TAGS
定義了當前模組的類型,編譯器在編譯時間會根據類型的不同有些差別,有些tags的module甚至不會被編譯至系統中。
LOCAL_MUDULE_TAGS主要有如下幾種:user debug eng tests optional samples shell_ash

shell_mksh。optional表示在所有版本的編譯條件下都被編譯至image中,剩下的表示在該版本中才會被編譯只image中,如user
表示在user版本下才會被編譯至image中。
對於包含LOCAL_PACKAGE_NAME的mk檔案,該項預設為optinal,具體可以參看build/core/package.mk。
SimpleJNI中定義為samples的具體作用我也不太清楚,為了保險起見,我自己的apk一般定義為optional。

      LOCAL_SRC_FILES 定義了編譯apk所需要的java代碼的目錄

      LOCAL_PACKAGE_NAME 這裡需要改成自己的package的名字

      LOCAL_JNI_SHARED_LIBRARIES 定義了要包含的so庫檔案的名字,如果你的程式沒有採用JNI,這行不需要。

      LOCAL_PROGUARD_ENABLED 定義了Java開發中的ProGuard壓縮方法,主要用來分析壓縮程式的,在我自己的應用中我沒有加這行。

      include $(BUILD_PACKAGE) 這行是build的關鍵,表示當前java代碼build成apk

      include $(call all-makefiles-under,$(LOCAL_PATH)) 表示需要build該目錄下的子目錄的檔案,這樣編譯系統就會在目前的目錄下的子目錄尋找Android.mk來編譯so等其它程式。

      根據上述所寫,建立我自己的Android.mk如下:

TOP_LOCAL_PATH:= $(call my-dir)

# Build activity

LOCAL_PATH:= $(TOP_LOCAL_PATH)
include $(CLEAR_VARS)

LOCAL_MODULE_TAGS := optional

LOCAL_SRC_FILES := $(call all-subdir-java-files)

LOCAL_PACKAGE_NAME := TestJniApp

LOCAL_JNI_SHARED_LIBRARIES := libtestjniapp

include $(BUILD_PACKAGE)

# ============================================================

# Also build all of the sub-targets under this one: the shared library.
include $(call all-makefiles-under,$(LOCAL_PATH))

      看起來很簡單吧,基本不需要改動即可。

  • Jni目錄下的Android.mk

      由於我們的TestJniApp是用JNI完成的,包含C原始碼,因此也需要一個jni目錄下的Android.mk。同樣首先看看SimpleJNI中jni目錄下的Android.mk的內容:

LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)

LOCAL_MODULE_TAGS := samples

# This is the target being built.
LOCAL_MODULE:= libsimplejni

# All of the source files that we will compile.
LOCAL_SRC_FILES:= /
  native.cpp

# All of the shared libraries we link against.
LOCAL_SHARED_LIBRARIES := /
        libutils

# No static libraries.
LOCAL_STATIC_LIBRARIES :=

# Also need the JNI headers.
LOCAL_C_INCLUDES += /
        $(JNI_H_INCLUDE)

# No special compiler flags.
LOCAL_CFLAGS +=

# Don't prelink this library.  For more efficient code, you may want
# to add this library to the prelink map and set this to true. However,
# it's difficult to do this for applications that are not supplied as
# part of a system image.

LOCAL_PRELINK_MODULE := false

include $(BUILD_SHARED_LIBRARY)

      LOCAL_MODULE 當前模組的名字,即編譯後的so檔案的名字

      LOCAL_SRC_FILES 所要編譯的檔案

      LOCAL_SHARED_LIBRARIES, LOCAL_STATIC_LIBRARIES 該模組要連結的動態庫和靜態庫。

      LOCAL_C_INCLUDES 要包含的標頭檔

      LOCAL_CFLAGS  C語言編譯選項

      LOCAL_PRELINK_MODULE 定義是否使用prelink工具,它用事先連結代替運行時連結的方法來加速共用庫的載入,不僅可以加快起動速度,還可以減少部分記憶體開銷。

      經過修改後,我自己的TestJniApp中jni目錄下的Android.mk如下:

LOCAL_PATH := $(call my-dir)

 

include $(CLEAR_VARS)

 

LOCAL_MODULE   
:= libtestjniapp

LOCAL_SRC_FILES := com_test_app_Jni.c

LOCAL_C_INCLUDES += $(JNI_H_INCLUDE)

 

LOCAL_PRELINK_MODULE := false

 

include $(BUILD_SHARED_LIBRARY)

 

  這裡有一點需要注意,如果要將so檔案編譯入image,必須要修改LOCAL_MODULE_TAGS,將原有的值samples修改為user,或者可以直接刪掉
。刪掉是因為對於包含LOCAL_MODULE的mk檔案,如果沒有指定LOCAL_MODULE_TAGS,該項預設為user,而只有定義為user的情況下,才會將so檔案編譯入image,具體定義可以參看build/core/base_rule.mk。

4.    修改/bulid/target/product/generic.mk 把工程編譯到系統中

      至此,還有最後一部工作。為了將工程編譯進入image,還需要在/bulid/target/product/generic.mk檔案中將package name添加進去

PRODUCT_PACKAGES := /
    AccountAndSyncSettings /
    CarHome /
    DeskClock /
    ……
    SyncProvider /
    TestJniApp

      

完成上面這些步驟後,在
source tree
根目錄下編譯
image
就可以了。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.