編輯:關於android開發
msm8909+android5.1.1編譯前配置及增加新項目和產品所需分支
編譯前的選項配置:
(1)source build/envseutp.sh
(2)choosecomb
1.source build/envsetup.sh
source 是用來運行 shell 腳本的命令 功能和 "." 和相同,因此 也可以寫作: . build/envsetup.sh
including device/lge/mako/vendorsetup.sh includingdevice/generic/mini-emulator-x86/vendorsetup.sh includingdevice/generic/mini-emulator-armv7-a-neon/vendorsetup.sh includingdevice/generic/mini-emulator-x86_64/vendorsetup.sh including device/generic/mini-emulator-mips/vendorsetup.sh includingdevice/generic/mini-emulator-arm64/vendorsetup.sh including device/qcom/common/vendorsetup.sh includingdevice/htc/flounder/vendorsetup.sh including device/asus/fugu/vendorsetup.sh includingdevice/asus/tilapia/vendorsetup.sh includingdevice/asus/grouper/vendorsetup.sh including device/asus/deb/vendorsetup.sh includingdevice/samsung/manta/vendorsetup.sh includingvendor/qcom/proprietary/common/vendorsetup.sh including sdk/bash_completion/adb.bash
2.choosecombo
Project choices are: 1. CB03 Which would you like? [CB03] 1 Build type choices are: 1. release 2. debug Which would you like? [1] 1 Product choices are: 1. msm8909 Which product would you like? [msm8909] 1 Variant choices are: 1. user 2. userdebug 3. eng Which would you like? [eng] 1 chipset are: 1. 8909 2. 8209 Which would you like? [8909] 1 Multisim choices are: 1. ssss 2. dsds Which would you like? [ssss] 1 ============================================ PLATFORM_VERSION_CODENAME=REL PLATFORM_VERSION=5.1.1 TARGET_PRODUCT=msm8909 TARGET_BUILD_VARIANT=user TARGET_BUILD_TYPE=release TARGET_BUILD_APPS= TARGET_ARCH=arm TARGET_ARCH_VARIANT=armv7-a-neon TARGET_CPU_VARIANT=cortex-a7 TARGET_2ND_ARCH= TARGET_2ND_ARCH_VARIANT= TARGET_2ND_CPU_VARIANT= HOST_ARCH=x86_64 HOST_OS=linux HOST_OS_EXTRA=Linux-3.16.0-30-generic-x86_64-with-Ubuntu-14.04-trusty HOST_BUILD_TYPE=release BUILD_ID=LMY47V SIMCOM_PROJECT=CB03 SIMCOM_MULTISIM=ssss OUT_DIR=out ============================================
上面內容對應envseup.sh的choosecombo函數,主要調用choosetype,chooseproduct,choosevariant等函數,確定TARGET_PRODUCT,TARGET_BUILD_TYPE,TARGET_BUILD_VARIANT。
function choosecombo() { chooseproject $1 echo choosetype $2 echo echo chooseproduct $3 echo echo choosevariant $4 #modify to display TARGET_CHIPSET and builddate dynamicly by xueguobing begin echo echo choose_CHIPSET $5 #modify to display TARGET_CHIPSET and builddate dynamicly by xueguobing end echo echo echo echo chooseMultisim $6 initbuildspec echo set_stuff_for_environment printconfig }
下面我們具體來看每個選項的內容
2.1 project choices(項目選擇)
Project choices are: 1. CB03 Which would you like? [CB03] 1 實現如下: PROJECT_CHOICES=(CB03 C6000) function chooseproject() { T=$(gettop) #獲取Android源碼根目錄 echo "Project choices are:" local index=1 local v for v in ${PROJECT_CHOICES[@]} do # The product name is the name of the directory containing # the makefile we found, above. echo " $index. $v" #比如顯示1.CB03 index=$(($index+1)) done local default_value=CB03 local ANSWER export SIMCOM_PROJECT= #導出環境變量 while [ -z "$SIMCOM_PROJECT" ] do echo -n "Which would you like? [$default_value] " if [ -z "$1" ] ; then read ANSWER else echo $1 ANSWER=$1 fi if [ -z "$ANSWER" ] ; then export SIMCOM_PROJECT=$default_value elif (echo -n $ANSWER | grep -q -e "^[0-9][0-9]*$") ; then if [ "$ANSWER" -le "${#PROJECT_CHOICES[@]}" ] ; then exportSIMCOM_PROJECT=${PROJECT_CHOICES[$(($ANSWER-1))]} fi else if check_project $ANSWER then export SIMCOM_PROJECT=$ANSWER else echo "** Not a validproject: $ANSWER" fi fi if [ -n "$1" ] ; then break fi done }
這裡導出了SIMCOM_PROJECT變量的值,比如C6000
加入我們要增加另個工程,比如C6000,要修改PROJECT_CHOICES的值,
修改前:
PROJECT_CHOICES=(CB03)
修改後:
PROJECT_CHOICES=(CB03 C6000)
中間不能用逗號。
基於上面的修改,所有項選擇之後輸出
read(): can't openbuild/buildplus/namespace/names.ini for read: 沒有那個文件或目錄 atbuild/buildplus/tool/qrdplus_target_gen.pl line 98.
target build Env generate failed, yourshould abort continuous make procedure!
此錯誤信息是initbuildspec()輸出的
function initbuildspec() { local -a GEN_QRDPLUS_ENV_RET GEN_QRDPLUS_ENV_PL=build/buildplus/tool/qrdplus_target_gen.pl #modify by lzq default mode is ct GEN_QRDPLUS_ENV_RET=(`perl $GEN_QRDPLUS_ENV_PL $SIMCOM_PROJECT`) if [ "$GEN_QRDPLUS_ENV_RET" != "GEN_SUCCESS" ] ;then echo "target build Env generate failed, your should abortcontinuous make procedure!" fi }
這裡會找build\buildplus\namespace\目錄下是否有names_ $(SIMCOM_PROJECT).ini的文件。所以需要在此目錄下增加names_C6000.ini文件才可以編譯通過。
2.2 build type選擇
Build type choices are: 1. release 2. debug Which would you like? [1] 1 實現如下: function choosetype() { echo "Build type choices are:" echo " 1. release" echo " 2. debug" echo local DEFAULT_NUM DEFAULT_VALUE DEFAULT_NUM=1 DEFAULT_VALUE=release export TARGET_BUILD_TYPE= local ANSWER while [ -z $TARGET_BUILD_TYPE ] do echo -n "Which would you like? ["$DEFAULT_NUM"] " if [ -z "$1" ] ; then read ANSWER else echo $1 ANSWER=$1 fi case $ANSWER in "") export TARGET_BUILD_TYPE=$DEFAULT_VALUE ;; 1) export TARGET_BUILD_TYPE=release ;; release) export TARGET_BUILD_TYPE=release ;; 2) export TARGET_BUILD_TYPE=debug ;; debug) export TARGET_BUILD_TYPE=debug ;; *) echo echo "I didn't understand your response. Please try again." echo ;; esac if [ -n "$1" ] ; then break fi done set_stuff_for_environment # 設置環境變量 }
這裡導出環境變量TARGET_BUILD_TYPE,其值為release或是debug,調用set_stuff_for_environment()來設置環境變量,如下:
function set_stuff_for_environment() { settitle set_java_home setpaths set_sequence_number export ANDROID_BUILD_TOP=$(gettop) #With this environment variable new GCC can apply colors to warnings/errors exportGCC_COLORS='error=01;31:warning=01;35:note=01;36:caret=01;32:locus=01:quote=01' }
2.3 product choices(產品選擇)
Product choices are: 1. msm8909 Which product would you like? [msm8909] 1 實現如下: # # This function isn't really right: It chooses a TARGET_PRODUCT # based on the list of boards. Usually, that gets you something # that kinda works with a generic product,but really, you should # pick a product by name. # function chooseproduct() { # Find the list of all products by lookingfor all AndroidProducts.mk files under the # device/, vendor/ andbuild/target/product/ directories and look for the format # LOCAL_DIR/and extract the name ProductSpecificFile from it. # This will give the list of all productsthat can be built using choosecombo local -a prodlist # Find all AndroidProducts.mk files underthe dirs device/, build/target/ and vendor/ # Extract lines containing .mk from them # Extract lines containing LOCAL_DIR # Extract the name of the product specificfile prodlist=(`/usr/bin/find device/qcom/msm8909 -name AndroidProducts.mk2>/dev/null| xargs grep -h \.mk| grep LOCAL_DIR| cut -d'/' -f2|cut -d' ' -f1|sort|uniq|cut -d'.' -f1`) export TARGET_PRODUCT= local index=1 local p echo "Product choices are:" for p in ${prodlist[@]} do echo " $index. $p" let "index = $index + 1" done if [ "x$TARGET_PRODUCT" != x ] ; then default_value=$TARGET_PRODUCT else default_value=msm8909 fi local ANSWER while [ -z "$TARGET_PRODUCT" ] do echo -n "Which product would you like? [$default_value] " if [ -z "$1" ] ; then read ANSWER else echo $1 ANSWER=$1 fi if [ -z "$ANSWER" ] ; then export TARGET_PRODUCT=$default_value elif (echo -n $ANSWER | grep -q -e "^[0-9][0-9]*$") ; then local poo=`echo -n $ANSWER` if [ $poo -le ${#prodlist[@]} ] ; then exportTARGET_PRODUCT=${prodlist[$(($ANSWER-1))]} else echo "** Bad productselection: $ANSWER" fi else if check_product $ANSWER then export TARGET_PRODUCT=$ANSWER else echo "** Not a validproduct: $ANSWER" fi fi if [ -n "$1" ] ; then break fi done set_stuff_for_environment }
這裡有幾個重要的信息:
(1)通過查找device、vendor和build/target/product/下AndroidProducts.mk文件來尋找所有的產品,尋找此目錄下LOCAL_DIR/
比如\device\qcom\msm8909\ AndroidProducts.mk,此文件內容如下:
PRODUCT_MAKEFILES := \
$(LOCAL_DIR)/msm8909.mk
提取msm8909.mk文件,msm8909就是一個產品。
我們如果要增加一個C6000的產品,需要做下面的處理:
(1)\device\qcom
基於此目錄的msm8909產品,增加C6000產品的目錄,然後修改AndroidProducts.mk文件內容如下:
PRODUCT_MAKEFILES := \
$(LOCAL_DIR)/C6000.mk
所以還需要基於msm8909.mk改為C6000.mk,然後把C6000.mk中關於msm8909產品和項目名稱為CB03的地方統一修改為C6000,但其中引用到的mixer_paths_msm8909_pm8916.xml文件這裡的msm8909不需要改為C6000,因為共用msm8909處理器,也需要把device\qcom\C6000\overlay\CB03改為C6000
(2)\vendor\qcom
沒有修改
(3)build/target/product/
沒有修改
(4)envsetup.sh從device/qcom枚舉所有的產品名
prodlist=(`/usr/bin/finddevice/qcom/msm8909 -name AndroidProducts.mk 2>/dev/null|
這是自帶的,如果枚舉所有的,可改為device/qcom,如果只想枚舉指定的,比如msm8909和C6000,可改為
prodlist=(`/usr/bin/finddevice/qcom/msm8909 device/qcom/C6000 -name AndroidProducts.mk 2>/dev/null|
(5)導出TARGET_PRODUCT,其值為msm8909或是C6000
(6)設置產品名稱的顯示順序
prodlist=(`/usr/bin/finddevice/qcom/msm8909 device/qcom/C6000 -name AndroidProducts.mk 2>/dev/null| xargs grep -h \.mk| grep LOCAL_DIR| cut -d'/' -f2|cut -d' ' -f1|sort|uniq|cut -d'.' -f1`) 顯示結果 Product choices are: 1. C6000 2. msm8909
這種方式會根據字母順序來顯示,如果想按照自己制定的順序來顯示,如下:
prodlist=(`/usr/bin/finddevice/qcom/msm8909 device/qcom/C6000 -name AndroidProducts.mk 2>/dev/null| xargs grep -h \.mk| grep LOCAL_DIR| cut -d'/' -f2|cut -d'.' -f1`) 顯示結果 Product choices are: 1. msm8909 2. C6000
2.4 variant choices不同的選擇
Variant choices are: 1. user 2. userdebug 3. eng Which would you like? [eng] 1 實現如下: VARIANT_CHOICES=(user userdebug eng) function choosevariant() { echo "Variant choices are:" local index=1 local v for v in ${VARIANT_CHOICES[@]} do # The product name is the name of the directory containing # the makefile we found, above. echo " $index. $v" index=$(($index+1)) done local default_value=eng local ANSWER export TARGET_BUILD_VARIANT= while [ -z "$TARGET_BUILD_VARIANT" ] do echo -n "Which would you like? [$default_value] " if [ -z "$1" ] ; then read ANSWER else echo $1 ANSWER=$1 fi if [ -z "$ANSWER" ] ; then export TARGET_BUILD_VARIANT=$default_value elif (echo -n $ANSWER | grep -q -e "^[0-9][0-9]*$") ; then if [ "$ANSWER" -le"${#VARIANT_CHOICES[@]}" ] ; then exportTARGET_BUILD_VARIANT=${VARIANT_CHOICES[$(($ANSWER-1))]} fi else if check_variant $ANSWER then export TARGET_BUILD_VARIANT=$ANSWER else echo "** Not a validvariant: $ANSWER" fi fi if [ -n "$1" ] ; then break fi done }
導出環境變量TARGET_BUILD_VARIANT,其值為(user userdebug eng)三選一。
2.5 chipset
chipset are: 1. 8909 2. 8209 Which would you like? [8909] 1 CHIPSET=(8909 8209) function choose_CHIPSET() { echo "chipset are:" local index=1 local v for v in ${CHIPSET[@]} do # The product name is the name of the directory containing # the makefile we found, above. echo " $index. $v" index=$(($index+1)) done local default_value=8909 local ANSWER export TARGET_CHIPSET= while [ -z "$TARGET_CHIPSET" ] do echo -n "Which would you like? [$default_value] " if [ -z "$1" ] ; then read ANSWER else echo $1 ANSWER=$1 fi if [ -z "$ANSWER" ] ; then export TARGET_CHIPSET=$default_value elif (echo -n $ANSWER | grep -q -e "^[0-9][0-9]*$") ; then if [ "$ANSWER" -le "${#CHIPSET[@]}" ] ; then exportTARGET_CHIPSET=${CHIPSET[$(($ANSWER-1))]} fi else if check_variant $ANSWER then export TARGET_CHIPSET=$ANSWER else echo "** Not a validvariant: $ANSWER" fi fi if [ -n "$1" ] ; then break fi done }
導出環境變量TARGET_CHIPSET,其值為8909或是8209。
2.6 multisim choices
Multisim choices are: 1. ssss 2. dsds Which would you like? [ssss] 1 MULTISIM_CHOICES=(ssss dsds) function chooseMultisim() { T=$(gettop) export SIMCOM_MULTISIM= local choose_multisim=0 local default_value= case $SIMCOM_PROJECT in "CB03") choose_multisim=1 default_value=ssss ;; *) choose_multisim=1 default_value=ssss ;; esac if [ $choose_multisim -eq 1 ] ; then echo "Multisim choices are:" local index=1 local v for v in ${MULTISIM_CHOICES[@]} do echo " $index. $v" index=$(($index+1)) done local ANSWER while [ -z "$SIMCOM_MULTISIM" ] do echo -n "Which would you like? [$default_value] " if [ -z "$1" ] ; then read ANSWER else echo $1 ANSWER=$1 fi if [ -z "$ANSWER" ] ; then export SIMCOM_MULTISIM=$default_value elif (echo -n $ANSWER | grep -q -e "^[0-9][0-9]*$") ; then if [ "$ANSWER" -le "${#MULTISIM_CHOICES[@]}" ] ;then exportSIMCOM_MULTISIM=${MULTISIM_CHOICES[$(($ANSWER-1))]} fi else if check_multisim $ANSWER then export SIMCOM_MULTISIM=$ANSWER else echo "** Not a validmultisim: $ANSWER" fi fi if [ -n "$1" ] ; then break fi done fi }
導出環境變量SIMCOM_MULTISIM,其值為ssss或是dsds
基於上面的修改後,然後編譯C6000,make –j4,遇到的問題如下:
(1)make: *** 沒有規則可以創建目標“build/scm_scripts/C6000.mk”。 停止
envsetup.sh下關於我們make這個動作的函數如下
function m() { local T=$(gettop) local DRV=$(getdriver $T) if [ "$T" ]; then $DRV make -C $T -f build/core/main.mk $@ else echo "Couldn't locate the top of the tree. Try setting TOP." fi }
可知會調用build/core/main.mk,此文件下通過TARGET_PRODUCT和SIMCOM_PROJECT環境變量搜索,相關部分如下
$(info********************************************) ifneq (,$(SIMCOM_PROJECT)) $(info ! override withvendor/simcom/$(SIMCOM_PROJECT) !) $(shell cp -rfvendor/simcom/$(SIMCOM_PROJECT)/frameworks ./) $(shell cp -rfvendor/simcom/$(SIMCOM_PROJECT)/packages ./) else $(info SIMCOM_PROJECT is null!) endif $(info********************************************) includebuild/buildplus/target/QRDExt_target.min ifeq ($(Module_Nfc_Pn547), yes) $(info ! override withvendor/simcom/Nfc_Pn547 !) $(shell cp -rf vendor/simcom/Nfc_Pn547/*./) endif #ifeq (build/scm_scripts/$(SIMCOM_PROJECT)_$(TARGET_CUSTOMER).mk,$(wildcard build/projectEnv/$(TARGET_PRODUCT)_$(TARGET_CUSTOMER).mk)) #includebuild/scm_scripts/$(SIMCOM_PROJECT)_$(TARGET_CUSTOMER).mk #else includebuild/scm_scripts/$(SIMCOM_PROJECT).mk #endif
可知要創建build/scm_scripts/C6000.mk這個文件,然後編譯
(2)make: *** 沒有規則可以創建“out/target/product/C6000/obj/ETC/init.rc_intermediates/init.rc”需要的目標“system/core/rootdir/init_C6000.rc”。 停止
所以我們需要創建system/core/rootdir/init_C6000.rc
(3)Can't find defaultconfiguration "arch/arm/configs/msm8909-1gb-C6000-perf_defconfig"!
所以需要創建msm8909-1gb-C6000-perf_defconfig文件,此文件中的CONFIG_ARCH_MSM8909_CB03=y改為CONFIG_ARCH_MSM8909_C6000=y,此配置在\kernel\arch\arm\mach-msm\Kconfig用到,增加內容:
config ARCH_MSM8909_C6000 bool "C6000 Product" depends on ARCH_MSM8909 help Support for MSM8909 C6000.
(4)make: *** 沒有規則可以創建“out/target/product/C6000/persist/WCNSS_qcom_wlan_nv.bin”需要的目標“device/qcom/C6000/WCNSS_qcom_wlan_nv_C6000.bin”。 停止。
把此目錄下的WCNSS_qcom_wlan_nv_CB03.bin改為WCNSS_qcom_wlan_nv_C6000.bin
(5)make: ***[out/target/product/C6000/obj/PACKAGING/target_files_intermediates/C6000-target_files-eng.zip]錯誤 1
更多的編譯錯誤信息如下:
Package target files:out/target/product/C6000/obj/PACKAGING/target_files_intermediates/C6000-target_files-eng.zip prepare the ota cp files.[vendor/simcom/C6000/mp_images] out/host/linux-x86/bin/acp vendor/simcom/C6000/mp_images/NON-HLOS.bin out/target/product/C6000/NON-HLOS.ota acp: file'vendor/simcom/C6000/mp_images/NON-HLOS.bin' does not exist make: ***[out/target/product/C6000/obj/PACKAGING/target_files_intermediates/C6000-target_files-eng.zip]錯誤 1 #### make failed to build some targets(39:57 (mm:ss)) ####
編譯生成了所需要的系統文件,但少了misc.img、msm8909-otg-eng.zip、NON-HLOS.ota、Package_backup.zip、rpm.ota、sbl1.otg、splash.img、target_files-package.zip、tz.ota
可知需要vendor/simcom/C6000/mp_images文件夾下的NON-HLOS.bin文件來生成C6000-target_files-eng.zip文件,所以我們需要創建vendor/simcom/C6000文件夾及需要的文件,
(6)編譯成功,但還是少了misc.img和splash.img
在vendor目錄下搜索misc,發現vendor\qcom\proprietary\qrdplus\Extension\apps\BootAnimation\Android.mk文件相關內容如下:
$(shell cp -r$(LOCAL_PATH)/$(SIMCOM_PROJECT)/splash.img $(PRODUCT_OUT)/splash.img) $(shell cp -r$(LOCAL_PATH)/$(SIMCOM_PROJECT)/misc.img $(PRODUCT_OUT)/misc.img)
可知要拷貝BOOtAnimation目錄下$(SIMCOM_PROJECT)下的splash.img、misc.img文件拷貝到$(PRODUCT_OUT)下,所以我們需要創建C6000的目錄及需要的文件。
(7)燒錄系統,開機的時候白屏,進入系統還是白屏,休眠喚醒後顯示和TP正常
改為采用CB03編譯出來的emmc_appsboot.mbn(uboot部分)就顯示OK了,說明和uboot有關。
/c4050-q4/bootable/bootloader/lk/project/msm8909.mk文件增加
ifeq ($(SIMCOM_PROJECT), C6000) DEFINES += MSM8909_C6000=1 Endif
bootable\bootloader\lk\target\msm8909\include\target\display.h
改為
#if (MSM8909_CB03 || MSM8909_C6000) static struct gpio_pin reset_gpio = { "msmgpio", 8, 3, 1, 0, 1 }; #else static struct gpio_pin reset_gpio = { "msmgpio", 25, 3, 1, 0, 1 }; #endif
然後顯示就OK了。
(8)用CB03編譯,大小為852MB;用C6000編譯,大小為846MB
編譯出來的系統在點擊桌面應用圖標的時候,有提示音,做下面的修改
\device\qcom\common\common.mk
ifneq (, $(filter CB03, $(SIMCOM_PROJECT)))
改為
ifneq (, $(filter CB03 C6000,$(SIMCOM_PROJECT)))
到此編譯出來的燒錄就不存在上面的問題。
(9)增加C6000相對應的設備樹文件
\kernel\arch\arm\boot\dts\qcom\Makefile增加
dtb-$(CONFIG_ARCH_MSM8909) +=msm8909-sim.dtb \下面增加
dtb-$(CONFIG_ARCH_MSM8909_C6000) +=msm8909-1gb-qrd-skue-c6000.dtb
增加msm8909-1gb-qrd-skue-c6000.dts,此文件需要#include "msm8909-qrd-skue-c6000.dtsi",所以需要增加msm8909-qrd-skue-c6000.dtsi文件
msm8909-qrd-skue-cb03.dtsi文件內容如下
#include"msm8909-qrd-cb03.dtsi"需要增加c6000對應的。 #include"msm8909-camera-sensor-skue.dtsi" #include"dsi-panel-otm9605ag-qhd-video.dtsi" //major QHD LCM replace otm9605a #include"dsi-panel-otm9605a-qhd-cb03-video.dtsi" //major QHD LCM replaceotm9605a CB03 #include"dsi-panel-otm9605a-qhd-video.dtsi" //majorQHD LCM #include"dsi-panel-hx8389bg-qhd-video.dtsi" //minorQHD LCM #include"dsi-panel-nt35512-fwvga-video.dtsi" //majorFWVGA LCM #include"dsi-panel-ili9806e-fwvga-video.dtsi" //minorFWVGA LCM #include"dsi-panel-jd9161ba-fwvga-video.dtsi" //minorFWVGA LCM replace ili9806e #include"dsi-panel-ili9806e-wvga-video.dtsi" //minorWVGA LCM
但因為我們C6000和cb03的video部分一樣,所以保留dsi-panel-otm9605a-qhd-cb03-video.dtsi,增加msm8909-qrd-c6000.dtsi文件,此文件下
#include "msm8909-cb03.dtsi"需要增加c6000對應的。 #include "msm8909-pm8909.dtsi" #include"msm8909-pinctrl-cb03.dtsi"需要增加c6000對應的。
(10) vendor\qcom\proprietary\common\config\device-vendor.mk,
此文件下有增PRODUCT_LIST += CB03
我這裡暫時沒有增加
PRODUCT_LIST += C6000
編譯出來的系統測試發現近距離傳感器無效,接著驗證。
Android Design Support Library——Navigation View,androidnavigation前沿 Android 從5.0開始引
Android面試准備 第一天 第2-4例 2、如果有個100M大的文件,需要上傳至服務器中,而服務器form表單最大只能上傳2M,可以用什麼方法。 個人理解:所謂表單最
【騰訊Bugly干貨分享】一步一步實現Android的MVP框架,buglyandroid本文來自於騰訊bugly開發者社區,非經作者同意,請勿轉載,原文地址:http:
Android 三級聯動選擇城市+後台服務加載數據庫,技術渣,大家將就著看 首先我們需要一個xml數據保存到數據庫,這裡我從QQ下面找到一個l