編輯:關於Android編程
android系統正以迅雷不及掩耳之勢沖擊著智能手機與平板電腦市場,它顛覆了傳統手機的概念,將手機與平板電腦進行了一次大洗牌,最可貴的是他的開放性(雖不是完全開放)吸引了一大批工程師去改造它,完善它,任何人都可以下載到它的源代碼一睹它的真面目。這一節講講這樣從頭配置一個屬於你的android系統,至於如何獲取android源代碼這裡就不講了。本文是在假設你已經從android官網上獲取了其源代碼的基礎上講解的。
1.Create a company directory in //vendor/.
mkdir vendor/<company_name>
這一步是先在vendor(供貨商) 下新建一個目錄,用你公司名字命名,沒有的公司的就隨便編一個吧(:
2.Create a products directory beneath the company directory you created in step 1.
mkdir vendor/<company_name>/products/
同上,創建一個目錄,用你產品的名字命名吧
3.Create a product-specific makefile, called vendor/<company_name>/products/<first_product_name>.mk, that includes at least the following code:
$(call inherit-product, $(SRC_TARGET_DIR)/product/generic.mk)
#
# Overrides
PRODUCT_NAME := <first_product_name>
PRODUCT_DEVICE := <board_name>
在/products/ 目錄下建立一個mk文件,內容格式如上所示,拿個mini6410.mk的例子給大家看看:
$(call inherit-product, $(SRC_TARGET_DIR)/product/generic.mk)
# Overrides
PRODUCT_MANUFACTURER := FriendlyARM
PRODUCT_BRAND := FriendlyARM
PRODUCT_NAME := mini6410
PRODUCT_DEVICE := mini6410
***************************************************
mini6410.mk的路徑為/Android-2.2/vendor/friendly-arm/products/mini6410.mk l;這也驗證了上述1,2兩步。
4.在上述*.mk文件中添加可選的定義,這個就不多說了。
5.In the products directory, create an AndroidProducts.mk file that point to (and is responsible for finding) the individual product make files.
#
# This file should set PRODUCT_MAKEFILES to a list of product makefiles
# to expose to the build system. LOCAL_DIR will already be set to
# the directory containing this file.
#
# This file may not rely on the value of any variable other than
# LOCAL_DIR; do not use any conditionals, and do not look up the
# value of any variable that isn't set in this file or in a file that
# it includes.
#
PRODUCT_MAKEFILES := /
$(LOCAL_DIR)/first_product_name.mk /
按照這個模板添加就是了。
6.Create a board-specific directory beneath your company directory that matches the PRODUCT_DEVICE variable <board_name> referenced in the product-specific make file above. This will include a make file that gets accessed by any product using this board.
mkdir vendor/<company_name>/<board_name>
在你公司的目錄下添加一個目錄,名字命名為板子的名字,如:Android-2.2/vendor/friendly-arm/mini6410,其中mini6410就是開發板的名字,這個目錄下的文件比較重要。接下來為了好敘述,就借用mini6410的例子吧。
7.在Android-2.2/vendor/friendly-arm/mini6410目錄下創建BoardConfig.mk文件
先看看這個文件的內容是怎樣的:
[cpp]
# config.mk
#
# Product-specific compile-time definitions.
#
# The generic product target doesn't have any hardware-specific pieces.
TARGET_CPU_ABI := armeabi
TARGET_NO_BOOTLOADER := true
TARGET_NO_KERNEL := true
TARGET_PROVIDES_INIT_RC := true
# Customized map
TARGET_PRELINKER_MAP := vendor/friendly-arm/products/prelink-linux-arm-FA.map
# Hardware 3D
TARGET_HARDWARE_3D := false
# Audio
BOARD_USES_ALSA_AUDIO := true
BUILD_WITH_ALSA_UTILS := true
# Camera
BOARD_CAMERA_LIBRARIES := libcamera
BOARD_S3CJPEG_LIBRARIES := libs3cjpeg
# Wi-Fi
BOARD_HAVE_LIBWIFI := true
#BOARD_WPA_SUPPLICANT_DRIVER := WEXT
BOARD_WPA_SUPPLICANT_DRIVER := CUSTOM
#CONFIG_DRIVER_NL80211 := true
WPA_BUILD_SUPPLICANT := true
#WPA_SUPPLICANT_VERSION := VER_0_6_X
CONFIG_CTRL_IFACE := y
# Bluetooth
BOARD_HAVE_BLUETOOTH := true
# GPS
BOARD_GPS_LIBRARIES :=libgps
BoardConfig.mk文件是干嘛的呢,從上面的例子代碼中你也許能猜出來,BoardConfig.mk是用來定制你的設備具有什麼功能的,比如說是否支持攝像頭,GPS導航等一些板級定制。該文件是我們定制android系統中比較重要的一個文件。
8.修改系統屬性。
該項不是必須的,但大部分情況下我們深度定制系統時都要修改系統屬性。
如何修改呢,在/Android-2.2/vendor/friendly-arm/mini6410/下創建一個system.prop文件,內如如下所示:
# system.prop for
# This overrides settings in the products/generic/system.prop file
#
# rild.libpath=/system/lib/libreference-ril.so
# rild.libargs=-d /dev/ttyS0
9.在/Android-2.2/vendor/friendly-arm/products添加AndroidProducts.mk文件,該文件下可包含多個board_name.mk文件,即多個設備。代碼如下所示:
PRODUCT_MAKEFILES := /
$(LOCAL_DIR)/first_product_name.mk /
$(LOCAL_DIR)/second_product_name.mk
10.在/Android-2.2/vendor/friendly-arm/mini6410下添加Android.mk文件,該文件至少包含以下內容:
[cpp] view plaincopy
# make file for new hardware from
#
LOCAL_PATH := $(call my-dir)
#
# this is here to use the pre-built kernel
ifeq ($(TARGET_PREBUILT_KERNEL),)
TARGET_PREBUILT_KERNEL := $(LOCAL_PATH)/kernel
endif
#
file := $(INSTALLED_KERNEL_TARGET)
ALL_PREBUILT += $(file)
$(file): $(TARGET_PREBUILT_KERNEL) | $(ACP)
$(transform-prebuilt-to-target)
#
# no boot loader, so we don't need any of that stuff..
#
LOCAL_PATH := vendor/<company_name>/<board_name>
#
include $(CLEAR_VARS)
#
# include more board specific stuff here? Such as Audio parameters.
到此為止,初步定制基本完成,該配置部分的架構如下圖所示:
Android以模塊的形式來組織各個系統中的部件,Eng專業點的詞匯就是Module,就是各位在幾乎每個目錄下都能看到的Android.mk。可以簡單地把Android所有的Make文件分為4種:
1、For config
這類文件主要來配置product,board,以及根據你的Host和Target選擇相應的工具以及設定相應的通用編譯選項:
build/core/config.mk summary of config
build/core/envsetup.mk generate dir config and so on
build/target/product product config
build/target/board board config
build/core/combo build flags config
這裡解釋下這裡的board和product。borad主要是設計到硬件芯片的配置,比如是否提供硬件的某些功能,比如說GPU等等,或者芯片支持浮點運算等等。product是指針對當前的芯片配置定義你將要生產產品的個性配置,主要是指APK方面的配置,哪些APK會包含在哪個product中,哪些APK在當前product中是不提供的。
config.mk是一個總括性的東西,它裡面定義了各種module編譯所需要使用的HOST工具以及如何來編譯各種模塊,比如說 BUILT_PREBUILT就定義了如何來編譯預編譯模塊。envsetup.mk主要會讀取由envsetup.sh寫入環境變量中的一些變量來配置編譯過程中的輸出目錄,combo裡面主要定義了各種Host和Target結合的編譯器和編譯選項。
2、 Module Compile
這類文件主要定義了如何來處理Module的Android.mk,以及采用何種方式來生成目標模塊,這些模塊生成規則都定義在config.mk裡面,我們可以看看:
CLEAR_VARS:= $(BUILD_SYSTEM)/clear_vars.mk
BUILD_HOST_STATIC_LIBRARY:= $(BUILD_SYSTEM)/host_static_library.mk
BUILD_HOST_SHARED_LIBRARY:= $(BUILD_SYSTEM)/host_shared_library.mk
BUILD_STATIC_LIBRARY:= $(BUILD_SYSTEM)/static_library.mk
BUILD_RAW_STATIC_LIBRARY := $(BUILD_SYSTEM)/raw_static_library.mk
BUILD_SHARED_LIBRARY:= $(BUILD_SYSTEM)/shared_library.mk
BUILD_EXECUTABLE:= $(BUILD_SYSTEM)/executable.mk
BUILD_RAW_EXECUTABLE:= $(BUILD_SYSTEM)/raw_executable.mk
BUILD_HOST_EXECUTABLE:= $(BUILD_SYSTEM)/host_executable.mk
BUILD_PACKAGE:= $(BUILD_SYSTEM)/package.mk
BUILD_HOST_PREBUILT:= $(BUILD_SYSTEM)/host_prebuilt.mk
BUILD_PREBUILT:= $(BUILD_SYSTEM)/prebuilt.mk
BUILD_MULTI_PREBUILT:= $(BUILD_SYSTEM)/multi_prebuilt.mk
BUILD_JAVA_LIBRARY:= $(BUILD_SYSTEM)/java_library.mk
BUILD_STATIC_JAVA_LIBRARY:= $(BUILD_SYSTEM)/static_java_library.mk
BUILD_HOST_JAVA_LIBRARY:= $(BUILD_SYSTEM)/host_java_library.mk
BUILD_DROIDDOC:= $(BUILD_SYSTEM)/droiddoc.mk
BUILD_COPY_HEADERS := $(BUILD_SYSTEM)/copy_headers.mk
BUILD_KEY_CHAR_MAP := $(BUILD_SYSTEM)/key_char_map.mk
除了CLEAR_VARS是清楚本地變量之外,其他所有的都對應了一種模塊的生成規則,每一個本地模塊最後都會include其中的一種來生成目標模塊。大部分上面的.mk都會包含base_rules.mk,這是對模塊進行處理的基礎文件,建議要寫本地模塊的都去看看,看明白了為什麼 Android.mk要這麼寫就會大致明白了。
3、Local Module
本地模塊的Makefile文件就是我們在Android裡面幾乎上隨處可見的Android.mk。Android進行編譯的時候會通過下面的函數來遍歷所有子目錄中的Android.mk,一旦找到就不會再往層子目錄繼續尋找(所有你的模塊定義的頂層Android.mk必須包含自己定義的子目錄中的Android.mk)。
subdir_makefiles += /
$(shell build/tools/findleaves.sh --prune="./out" $(subdirs) Android.mk)
不同類型的本地模塊具有不同的語法,但基本上是相通的,只有個別變量的不同,如何添加模塊在前面的帖子已經說過了,大家可以參考。
Android通過LOCAL_MODULE_TAGS來決定哪些本地模塊會不會編譯進系統,通過PRODUCT和LOCAL_MODULE_TAGS來決定哪些應用包會編譯進系統,如果用戶不指定LOCAL_MODULE_TAGS,默認它的值是user。此外用戶可以通過buildspec.mk來指定你需要編譯進系統的模塊。
用戶也可以通過mm來編譯指定模塊,或者通過make clean-module_name來刪除指定模塊。
4、Package
這主要指的是build/core/Makefile這個文件,它定義了生成各種img的方式,包括ramdisk.img userdata.img system.img update.zip recover.img等。我們可以看看這些img都是如何生成的,對應著我們常用的幾個make goals:
在實際的過程中,我們也可以自己編輯out目錄下的生成文件,然後手工打包相應生成相應的img,最常用的是加入一些需要集成進的prebuilt file。
所有的Makefile都通過build/core/main.mk這個文件組織在一起,它定義了一個默認goals:droid,當我們在TOP目錄下敲Make實際上就等同於我們執行make droid。當Make include所有的文件,完成對所有make我文件的解析以後就會尋找生成droid的規則,依次生成它的依賴,直到所有滿足的模塊被編譯好,然後使用相應的工具打包成相應的img。
基本上Android building system就是以這樣一種方式組織在一起的了,下面說一點閒散的東西。首先是如何來加快Android的編譯過程,因為每次Android都要遍歷所有的Android.mk,不管是編譯整個工程還是只編譯某個模塊。所以可以將遍歷的結果保存下來,下次直接從文件讀就好了,但是這裡容易出錯,所以一定要確認是否正確包含了所有的.mk,當新加入文件的時候確認將原來保存的文件刪除。下面是我寫的加快編譯的一個makefile,將下面的語句替換掉 main.mk中的相應部分就可以了:
FROM:
subdir_makefiles += /
$(shell build/tools/findleaves.sh --prune="./out" $(subdirs) Android.mk)
TO:
ifneq ($(ONE_SHOT_MAKEFILE),)
else
ifneq ($(CASH_MK),true)
subdir_makefiles += /
$(shell build/tools/findleaves.sh --prune="./out" $(subdirs) Android.mk)
else
subdir-makefiles-cash := $(shell cat build/subdir_mk_cash)
ifeq ($(subdir-makefiles-cash),)
$(warning No .mk cash ,create now !)
subdir_makefiles += /
$(shell build/tools/findleaves.sh --prune="./out" $(subdirs) Android.mk)
mk-to-file := $(shell echo $(subdir_makefiles) > build/subdir_mk_cash)
else
$(warning Using cash mk !)
subdir_makefiles := $(shell cat build/subdir_mk_cash)
endif
endif
endif
通過CASH_MK=true來打開快速編譯的功能,因為沒有對錯誤進行檢測的操作,所以使用的時候一定要特別小心。
最後一個是擴展SDK API的問題,Android可以編譯出自己的SDK,並擴展相應的SDK API,現在沒有仔細的研究,只了解一個粗暴的方法就是在frameworks/base/core/java中添加相應的類。
ViewAnimator繼承了FrameLayout,多個組件重合在一起,可以加入多個組件,然後切換的時候會有動畫。ViewAnimator及其子類的繼承關系ViewAn
前言我們已經開發了一個應用,這裡稱為A應用,類似於天氣weather那種。現在的任務就是如果這些A應用有新版本了,或者天氣出現比較惡劣的狀況,要及時在手機上進行消息的推送
一 、 虛擬機的安裝常見的虛擬機產品有 VMware 公司的 VMware Workstation、Oracle 公司的 VirtualBox。因為 VMware 體積相
觀察者模式(Observer)觀察者模式是對象的行為模式,又被叫做為模型-視圖模式。這種模式定義了一種一對多的依賴關系,使多個觀察者對象同時監聽某個角色對象。一旦這個角色