




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、第一章搭建開發(fā)環(huán)境“工欲善其事,必先利其器”。在開始定制 MIUI ROM 之前,發(fā)環(huán)境。需要搭建好必要的開本的主旨是如何基于原廠ROM 修改所涉及的修改理論上說是不需要源碼的,對(duì)源碼開發(fā)感一份的可以參照 HYPERLINK http:/s/ http:/s。對(duì)于 ROM 開發(fā)者來說,建議發(fā)布的 android 源碼,這不是必須的,但是對(duì)于理解排查 ROM 適配中的一些錯(cuò)誤有很大的幫助。.操作系統(tǒng)定制 MIUI ROM 所涉及的技術(shù)本身對(duì)操作系統(tǒng)沒有特殊要求,Windows,Linux 和 Mac 系統(tǒng)都可以。但是 patchrom 項(xiàng)目是基于 Linux 開發(fā)的,確切的說,是基于 Ubunt
2、u 開發(fā)的,我們使用 Ubuntu10 以上的系統(tǒng)。目前,還沒有計(jì)劃開發(fā)運(yùn)行在 Windows 和 Mac 系統(tǒng)上面的 patchrom 項(xiàng)目。2.安裝 Android SDK本節(jié)只簡(jiǎn)要介紹如何在 Ubuntu 系統(tǒng)上安裝 Android SDK。2.1 安裝 JDK首先需要安裝 Java 開發(fā)工具包,本文中約定$表示 Terminal 中令提示符,其后的文字表示輸入令。從以下地址 httJava 開發(fā)工具包./technetwork/java/javase/downloads/index.htmlJava SE 6 Update38 版本。對(duì)下來的文件進(jìn)行安裝:sudood 755 jdk-
3、6u38-linux-x64.bin sudo -s ./jdk-6u38-linux-x64.bin /opt$接下來編輯 home 目錄下的.bashrc 文件,配置vim /.bashrc在文件最后添加:set java environment所需要的 PATH 環(huán)境變量:$#JAVA_HOME=/opt/jdk1.6.0_38export JRE_HOME=$JAVA_HOME/jreexport CLASSPATH=.:$JAVA_HOME/lib:$JRE_HOME/libexport PATH=$JAVA_HOME/bin:$PATH運(yùn)行命令來使$ ./.bashrc修改的 PA
4、TH 環(huán)境變量生效。最后檢查$ java -ver的 JDK 是否安裝成功,輸入:出現(xiàn)如下提示,說明安裝成功,如不成功,請(qǐng)參照以上步驟再次嘗試。2.2Android SDK 包從以下地址Android SDK 包ht/android/android-sdk_r21.0.1-linux.tgz解壓到你的 home 目錄下,假定解壓后的目錄為/home/patcher/android-sdk-linux。接下來編輯 home 目錄下的.bashrc 文件,修改 PATH 環(huán)境變量:export PATH=/android-sdk-linux/platform-tools:/android-sdk-
5、linux/tools:$PATH運(yùn)行命令來使修改的 PATH 環(huán)境變量的修改生效。$ ./.bashrc2.3 安裝運(yùn)行命令 android 來啟動(dòng) Android SDK Manager$ android安裝完成的結(jié)果如下圖所示:選中 Androd SDK Tools 和 Android SDK Platform-tools,然后點(diǎn)擊安裝,接下來跟隨應(yīng)用程序的說明進(jìn)行安裝。這一步完成后,所需要的 Android SDK 也安裝完畢了。注:在裝 Eclipse,定制 MIUI/sdk/installing.html 網(wǎng)頁中,大家會(huì)看到需要安ROM 不需要安裝 Eclipse,這個(gè)是開發(fā) An
6、droid 程序所需要的。2.4 adbAndroid SDK 中對(duì)的過程中,最常用錯(cuò)誤。最重要的工具是 adb(android debug bridge)以及 aapt。在適配令是 adb logcat,該命令會(huì)打印出詳細(xì)的調(diào)試信息,幫助定位為了驗(yàn)證 adb 是否工作,同時(shí)也是驗(yàn)證上述步驟是否成功,打開中的系統(tǒng)設(shè)置開發(fā)選項(xiàng),確保選中“USB 調(diào)試”,然后用 USB 線連接你機(jī),在 Ubuntu S下運(yùn)機(jī)了。行命令 adb deviList of devi ACE87B700C0A,如果顯示的信息和下面類似,那么恭喜你,adb 能識(shí)別你 attacheddevice注意:在 Ubuntu 下,
7、有可能會(huì)提示“no such permiss”,這個(gè)時(shí)候有兩個(gè)辦法,第一種是以 root 的運(yùn)行 adb。第二種方法:a) 運(yùn)行 lsusb 命令,對(duì)于,輸出如下:1d6b:0002 Linux Foundation 2.0 root hub 04e8:685e Samsung Electronics Co.,Bus 002Bus 001。找到Device 001:IDDevice 098:ID對(duì)應(yīng)的那一行,下 04e8:685e,這個(gè)分別表示該設(shè)備的 vendorld 和productID。如果不確定找到區(qū)別的那一行。對(duì)應(yīng)的是哪一行,可以在連上前后運(yùn)行 Isusb,b) 在/etc/udev
8、/rules.d 目錄下新建一個(gè)文件 99-android.rules。編輯如下: SUBSYSTEMS=”usb”, ATTRSidVendor=”04e8”,ATTRSidProduct=”685e”,MODE=”0666” , OWMER=”登錄用戶名”c) 重啟 usb 服務(wù),sudo restart udev, 重連。3.同步 MIUI 代碼創(chuàng)建一個(gè) patchrom 目錄:$ mkdir patchrom安裝 repo:$mkdir /bin vim /.bashrc將 PATH=/bin:$PATHcurl https:/od a+x /bin/repo$/dl/source/g
9、it-repo/repo /bin/repo切換到 patchrom 目錄:$cd patchromrepo init -u/MiCode/patchrom.git -b jellybean42-mtkreync4.patchrom 項(xiàng)目下面介紹 patchrom 的目錄結(jié)構(gòu)以及各目錄的作用。android:該目錄下面有 5 個(gè)子目錄。其中 src 目錄和將要介紹的 miui/src 目錄是一對(duì)一的關(guān)系。android/src 是發(fā)布的 android 源碼,miui/src 是 miui 在源碼基礎(chǔ)上所做的修改。為了節(jié)省空間,在這兩個(gè)目錄下面,的文件。framework.jar.out,an
10、droid.policy.jar.out,servi只放了 miui 修改過.jar.out 是 miui 修-framework 是改過的文件,與-framework 下面的文件是一對(duì)一的關(guān)系,基于 android 源碼制作的,沒有進(jìn)行過修改。build:該目錄是一些與編譯相關(guān)的,包含了所有的 makefile 的構(gòu)建。miui:該目錄下主要有 2 個(gè)子目錄:system 和 src。system 目錄下存放了的是由 miui源碼編譯后的文件,這些文件是tools:該目錄下面包含了所有的定制 MIUI ROM 所需要用到的所有文件。和工具程序,在編譯過程中需要使用這些程序。接 下來 /hom
11、e/patch開始 編譯 生成 i9300 的 定制 MIUI ROM ,假 定當(dāng) 前目錄 為atchrom 目錄,$. build/envsetup.sh cd i9300make fullota以上命令運(yùn)行完畢后,在 i9300 目錄下會(huì)生成一個(gè) out 子目錄, 在子目錄下的fullota.zip 文件就是發(fā)布的 i9300 的刷機(jī)包了,可以通過 recovery 刷入你的 i9300。MIUI 一直堅(jiān)持每周五的更新,稱為橙色過程。五,下面就讓來體驗(yàn)一下 OTA 的制作假定制作了 3.1.18 的 fullota,在 out 目錄下面有_files.zip,將它重命名為 last_候,在
12、 out 目錄下面, 是靠這個(gè)兩個(gè)文件來實(shí)現(xiàn)_files.zip。在 3.1.25 的時(shí)候,重新進(jìn)行 fullota,這個(gè)時(shí)就有了,last_files.zip 和_files.zip,就OTA。這里需要注意的是,上一個(gè)版本里面的_files必須重命名,不然會(huì)在你重新 fullota 以后被替換成新的文件,就不能實(shí)現(xiàn) OTA 的了。假定當(dāng)前的目錄為/home/patch$ . build/envsetup.sh$ ./tools/releasetools/ota_from_ out/_files.zip ota_upate.zip-k:指定簽名的 keyatchrom,_files -k ./
13、build/security/testkey -i last_files.zip-i:指定指定上次的_filesout/_files.zip:指的是這次新的_filesota_update.zip:指定生成的 OTA 包的文件名第二章 認(rèn)識(shí) Android1.bootloader當(dāng)拿到一款,第一件事情應(yīng)該就是安裝上電池,然后按下電源鍵開機(jī)。那么,從開機(jī)到進(jìn)入到桌面程序,這中間到底發(fā)生了些什么呢,就從下面這張簡(jiǎn)化了機(jī)結(jié)構(gòu)圖開始的探秘之旅:注意:該結(jié)構(gòu)圖并不反映的實(shí)際分區(qū)順序和位置,只是一個(gè)邏輯結(jié)構(gòu)圖。大家可以簡(jiǎn)單的把的 ROM類比為電腦上的硬盤,這個(gè)硬盤被分成了幾個(gè)分區(qū):bootloader 分
14、區(qū),boot 分區(qū),system 分區(qū)等。后面會(huì)逐個(gè)介紹各個(gè)分區(qū)的用途。所謂的刷機(jī)安裝操作系統(tǒng)??梢院?jiǎn)單的理解為是把安裝在的某些分區(qū)中,類似在電腦上面當(dāng)按下電源鍵通電啟動(dòng)后,首先從 bootloader 分區(qū)中一個(gè)固定的地址開始執(zhí)行指令。bootloader 分區(qū)可以分成兩個(gè)部分,分別叫做 primary bootloader 和 secondarybootloadrimary bootloader 主要執(zhí)行硬件檢測(cè)的功能,確保硬件能正常工作后將secondary stage bootloader 拷貝到內(nèi)存(RAM)中開始執(zhí)行。Secondary stage bootloader會(huì)進(jìn)行一些硬
15、件初始化的工作,比如獲取內(nèi)存大小信息等,然后根據(jù)用戶的按鍵進(jìn)入到某種啟動(dòng)模式。比如,大家所熟悉的通過電源鍵和其他一些按鍵的組合,可以進(jìn)入到 recovery,fastboot 或者選擇啟動(dòng)模式的啟動(dòng)界面等等。在上面看到的 bootloader 通常指的是 secondary stage bootloader。不過不需要關(guān)心太多的細(xì)節(jié),可以簡(jiǎn)單地理解為bootloader 就是一段啟動(dòng)代碼,根據(jù)用戶按鍵有選擇的進(jìn)入某種模式。fastboot 模式:fastboot 是 android 定義的一種簡(jiǎn)單地刷機(jī)協(xié)議,用戶可以通過fastboot 命令行工具來進(jìn)行刷機(jī)。比如:fastboot flash
16、 boot boot.img,這個(gè)命令就能把 boot.img 刷寫進(jìn) boot 分區(qū)中。一般了顯示他們的牛 B 之處,總是會(huì)提供自己廠家不會(huì)直接提供 fastboot 模式刷機(jī),而是為的刷機(jī)工具和刷機(jī)方法。比如說:三星的 Odin,摩托羅拉的 RSD,寫到各個(gè)分區(qū)中。的粉屏等等。但是,他們的本質(zhì)實(shí)際上是相同的,都是將程序直接刷recovery 模式:當(dāng)進(jìn)入 recovery 模式時(shí),secondary stage bootloader 從 recovery分區(qū)開始啟動(dòng),recovery 分區(qū)是一個(gè)獨(dú)立的 Linux 系統(tǒng),當(dāng) recovery 分區(qū)上的 Linux 內(nèi)核啟動(dòng)完畢后,開始執(zhí)行第
17、一個(gè)程序 init(init 程序是 Linux 系統(tǒng)所有程序的老)。init會(huì)啟動(dòng)一個(gè)叫做 recovery 的程序(recovery 模式的名稱也是由此而來)。通過 recovery 程序,用戶可以執(zhí)行清除數(shù)據(jù), 安裝刷機(jī)包等操作。一般機(jī)廠家都提供一個(gè)簡(jiǎn)單的recovery 程序,而大名鼎鼎的 CWM Recovery 就是一個(gè)加入了很多增強(qiáng)功能的 recovery 程序,要想用上 CWM Recovery 的前提是 recovery 分區(qū)可以被刷寫。大家在上面看到的解鎖 bootloader,一般指的是recovery 或者 fastboot,允許刷寫 recovery 分區(qū),這樣大家就
18、能用上喜愛的 CWM Recovery 了。MIUI 也為大家準(zhǔn)備了 recovery,是按照的 ROM 的風(fēng)格進(jìn)行設(shè)計(jì)的,利用觸屏進(jìn)行控制。Recovery 的源碼也已經(jīng)在上面開源,大家可以進(jìn)行,recovery 的制作,也會(huì)盡快的整理進(jìn)行發(fā)布。除了普通的 CPU以外,還有 MODEM 處理器。該的功能就是實(shí)現(xiàn)必須的通信功能,大家通常所刷的 RADIO 就是刷寫的 modem 分區(qū)。2.常啟動(dòng)當(dāng)只是按下電源鍵開機(jī)時(shí),會(huì)進(jìn)入正常啟動(dòng)模式。Secondary stage bootloader會(huì)從 boot 分區(qū)開始啟動(dòng)。Boot 分區(qū)的格式是固定的,首先是一個(gè)頭部,然后是 Linux 內(nèi)核,最后
19、是用作根文件系統(tǒng)的 ramdisk。當(dāng) Linux 內(nèi)核啟動(dòng)完畢后,就開始執(zhí)行根文件系統(tǒng)中的 init 程序,init 程序會(huì)啟動(dòng)文件(init.rc 和 init.x.rc)。啟動(dòng)文件的格式大家可以在網(wǎng)上找到很多參考資料。在原廠 ROM 上移植 MIUI 的原則是不修改 boot 分區(qū),因?yàn)橛幸恍C(jī)型無法修改boot 分區(qū)。根文件系統(tǒng)中有一個(gè)重要的配置文件,叫 p,該文件的內(nèi)容一般為:# #ADDITIONAL_DEFAULT_PROPERTIES#正ro.secure=1 ro.allow.mock.location=1 ro=debuggable=0persist.service.adb
20、.enable=1。文件中的每一行對(duì)某個(gè)屬性賦值,在后續(xù)的文章中還會(huì)談到屬性。這里面大家需要注意兩個(gè)屬性:ro.secure 和 ro.debuggable。如果 ro.secure=0,則允許運(yùn)行 adb root命令,通常大家說的內(nèi)核 ROOT 指的就是 ro.secure=0.而一般所說的 ROOT 權(quán)限指的是上有一個(gè)名為管理的程序(Superuser.apk)可以程序 root 用戶的。init 程序分區(qū)程序,下一節(jié)啟動(dòng),執(zhí)行中指定的動(dòng)作和命令中的一部分是運(yùn)行 system就來看看 system 分區(qū)的結(jié)構(gòu)。3.System 分區(qū)在講 system 分區(qū)之前,先來看一下這張 Andro
21、id 的系統(tǒng)架構(gòu)圖。從上到下依次為:應(yīng)用層:這一層就是大家平常所接觸的各種各樣的系統(tǒng)的自帶應(yīng)用,比如聯(lián)系人,音樂等。應(yīng)用層往下就是開發(fā)所接觸的??蚣軐樱哼@一層是 Android 系統(tǒng)的,它提供了整個(gè) Android 系統(tǒng)的機(jī)制,像窗口管理,程序安裝包管理,開發(fā)所接觸的 activity,service,broadcast 等。JNI 層:JNI 層是 Java 程序和底層操作系統(tǒng)通信的一個(gè)機(jī)制,它使得 Java 代碼可以調(diào)用 C/C+代碼來底層操作系統(tǒng)的 API。Dalvik 虛擬機(jī):Android 開發(fā)使用 Java 語言,應(yīng)用程序的 Java 代碼會(huì)被編譯成 dalvik虛擬機(jī)字節(jié)碼,這些
22、字節(jié)碼由 dalvik 虛擬機(jī)執(zhí)行。本地庫(kù):本地庫(kù)一般是有 C/C+語言所開發(fā)的,直接編譯成相應(yīng) CPU 的機(jī)器碼,這其中包含標(biāo)準(zhǔn) C 庫(kù),用以繪制圖形的 skia 庫(kù),瀏覽器引擎 webkit 等。HAL:硬件抽象層,為了和各個(gè)廠家的不同硬件相互配合工作,Android 定義了一臺(tái)硬件接口,比如說為了使用相機(jī),廠家的相機(jī)驅(qū)動(dòng)必須提供接口方法,這樣使得上層的代碼可以獨(dú)立于不同的硬件運(yùn)行。廠家適配層:本來 Android 定義的 HAL 層是直接和廠家提供的設(shè)備驅(qū)動(dòng)打交道的,但是目前廠家不想開源 HAL 部分的代碼,因此很多廠家都提供了一個(gè)我稱之為廠家是賠償呢過的代碼,這樣在 HAL 層接口的實(shí)
23、現(xiàn)只是一個(gè)簡(jiǎn)單地對(duì)的廠家適配層接口函數(shù)的調(diào)用。內(nèi)核:這一層就是大家熟悉的 Linux 內(nèi)核,內(nèi)核包含了各種硬件驅(qū)動(dòng),這些驅(qū)動(dòng)不同的廠家機(jī)是不一樣的。Linux 內(nèi)核是支持驅(qū)動(dòng)模塊化機(jī)制的,簡(jiǎn)單地說就是允許用戶動(dòng)態(tài)的加載或者卸載某個(gè)硬件驅(qū)動(dòng),但是目前看來,單獨(dú)加載外,其它驅(qū)動(dòng)都是和內(nèi)核綁定在一起的。廠家除了提供 WIFI 驅(qū)動(dòng)從這張結(jié)構(gòu)圖來看,除了內(nèi)核是放在 boot 分區(qū)外,其它層的代碼都是在 system 分區(qū)中,下面結(jié)合這張圖來介紹 system 分區(qū)的主要目錄內(nèi)容:system/app:app 目錄下存放的是應(yīng)用,也就是大家熟知的系統(tǒng) APP,這些系統(tǒng)自帶的程序是不能簡(jiǎn)單的卸載的,要通過
24、一些特殊的方式才能刪除(大家熟悉的是 ROOT 完了以后,使用 RE 文件管理器)。法就system/lib:目錄下存放的是組成 JNI 層,Dalvik 虛擬機(jī),本地庫(kù),HAL 層和廠家適配層的所有動(dòng)態(tài)庫(kù)(.so 文件)。system/framework:該目錄下存放的是框架層的 JAR 包,其中對(duì)適配 MIUI 來說,有 3個(gè)最重要的 JAR 包(framework.jar,android.policy.jar,servi會(huì)重點(diǎn)介紹這 3 個(gè) JAR 包。.jar)。后面system/fonts:該目錄下存放的是系統(tǒng)缺省的字體文件。system/media:該目錄下存放的是系統(tǒng)所使用的各種
25、文件,比如開機(jī)動(dòng)畫,壁紙文件等。不同機(jī)該目錄的組織方式可能不一樣。system/bin:該目錄下存放的是一些可執(zhí)行文件,基本上是由 C/C+編寫的。system/xbin:該目錄下存放的是一些擴(kuò)展的可執(zhí)行文件,所以該目錄可以為空。大家常用的 busybox 就放在該目錄下面。Busybox 所建立的各種符號(hào)錄下。命令也都在這個(gè)目system/build.prp 和上節(jié)說的根文件系統(tǒng)中的 p 文件格式一樣,都稱為屬性配置文件。他們都定義了一些屬性值,代碼可以性值。屬性值有一些命名規(guī)范:ro 開頭的表示只讀屬性,即這些屬性的值得代碼是無法修改的。或者修改這些屬persist 開頭的表示這些屬性值會(huì)
26、保存在文件中,這樣重新啟動(dòng)之后這些值還會(huì)保留。其它的屬性一般以所屬的類別開頭,這些屬性是可讀可寫的,但是對(duì)它們的修改重啟之后不會(huì)保留。很多 romer 都會(huì)修改一下 p 信息,里面的一些以 ro.build 開頭的屬性就是你在設(shè)置中的關(guān)于里看到的。可以通過修改 p 文件來將這個(gè) ROM 打上自己的印記。system/etc:該目錄存放一些配置文件,和屬性配置文件不一樣,這下面的配置文件可能稍微沒那么的有規(guī)律。一般來說,一些程序,還有大家所熟悉的 GPS 配置文件(gps.conf)和 A配置文件(-conf.xml)放在這個(gè)目HTC 的特效相機(jī)所使用的一些文件也放在這個(gè)目錄下。4.data 和
27、 cache 分區(qū)這一節(jié)簡(jiǎn)單的介紹一下 data 和 cache 分區(qū)。當(dāng)開機(jī)進(jìn)入桌面程序后,一般來說我們會(huì)安裝一些 APP,這些 APP 都安裝在 data/app 目錄下。所有的 Android 程序生成的數(shù)據(jù)基本上都保存在 data/data 目錄下。Wipe data 實(shí)質(zhì)上就是格式化 data 分區(qū),這樣我們安裝的所有 APP 和程序數(shù)據(jù)就丟失了。Cache 分區(qū)從名字上來看是用來緩存一些文件的,比如說一些音樂的臨時(shí)文件,或者管理的內(nèi)容存放在這個(gè)分區(qū)。5.小結(jié)本章主要是介紹 Android的硬結(jié)構(gòu)以及主要分區(qū)的內(nèi)容,并簡(jiǎn)要的介紹了一些開機(jī)啟動(dòng)過程。了解這些內(nèi)容有助于在整體上理解 RO
28、M 適配。第三章 尋找合適的原廠 ROM1.熟悉適配的機(jī)型1.1 逛刷機(jī)想要何刷機(jī)的。外的一個(gè)先學(xué)會(huì)被打,想做刷機(jī)學(xué)會(huì)刷機(jī)。先去各大逛逛,了解你的機(jī)型是如不得不提到一個(gè)避光的:./。這是國(guó),該技術(shù)性強(qiáng),用戶富有精神,機(jī)型全面。這個(gè)期間一定要掌握你的機(jī)型的刷機(jī)方法,需要用到的工具,多刷幾個(gè) ROM,熟悉刷機(jī)過程。1.2 合適的原廠 ROM在第一步熟悉了要移植的機(jī)型,刷了各個(gè)版本的 ROM 后,接下來要開始集中精力尋找一個(gè)合適的原廠 ROM。一般來說,原廠 ROM 的穩(wěn)定性好。這個(gè)時(shí)候能找到那種在原廠 ROM的基礎(chǔ)上僅做過 ROOT 和 deodex 的版本是最好的。那么如何判斷一個(gè)原廠 ROM
29、是否合適呢?首先要版本合適,這個(gè)系統(tǒng)的是基于原廠 ROM 適配 MIUI,目前 4.0 的 MIUI 是基于 android4.0.4 源碼開發(fā)的,從 android4.0.1 到 android4.0.4 這幾個(gè)版本變化都不太大,因此 4.0.1 到 4.0.4 的原廠 ROM 版本都是合適的。其次檢查所安裝的 ROM 是否有 root 權(quán)限。Root 權(quán)限分兩種:第一種是root:這種 root 權(quán)限的外在表現(xiàn)是你機(jī)上安裝了一個(gè)管理;第二種是內(nèi)核 root:這種 root 權(quán)限的外在表現(xiàn)如下:在 Ubuntu S下運(yùn)行如下命令:$adb root(該命令的含義是以 root 權(quán)限運(yùn)行 ad
30、b)$adb remount(該命令的含義是將 system 分區(qū)的權(quán)限設(shè)成可讀可寫)如果這兩條命令都成功,表明內(nèi)核 root。運(yùn)行 adb s為#。,可以看到s提示符如果上述兩條命令失敗了,運(yùn)行 adb s可以看到s提示符為$。如果此時(shí)管理程序。這種情況運(yùn)行 su 命令,彈出是否授予 root 權(quán)限,這說明上安裝了下運(yùn)行 su 命令后,s提示符也會(huì)變?yōu)?。在之后的章節(jié)會(huì)看到,適配 MIUI 的關(guān)鍵是能修改 system 分區(qū)的內(nèi)容,這兩種 root權(quán)限都可以將 system 分區(qū)設(shè)成可讀寫的,只是內(nèi)核 root 權(quán)限提供了最大的方便性,強(qiáng)烈推薦找到一個(gè)內(nèi)核 root 過的 ROM。Patch
31、rom 項(xiàng)目提供的工具和是基于你機(jī)獲取了內(nèi)核 root 權(quán)限,如果是root,也是可以的,但是需要修改一下子。因?yàn)橹皇莚oot,adb remount 命令會(huì)失敗。這個(gè)時(shí)候需要在s里重新 remount system 分區(qū),并且修改 system 的目錄權(quán)限,這樣才能修改 system 分區(qū)的內(nèi)容,而且需要修改提供的某些。(之后不針對(duì)root 權(quán)限做出特殊說明,相信你知道如何在這種模式下修改 system 分區(qū))。最后檢查所選擇的 ROM 可以進(jìn)入 Recovery 模式刷機(jī),不一定要求必須是 CWM Recovery,有 wipe dache 和安裝 zip 包等功能的簡(jiǎn)單 Recovery
32、 就可以,當(dāng)然有 CWM Recovery是更好了。針對(duì)每個(gè)機(jī)型,要想自動(dòng)生成 MIUI ROM 刷機(jī)包,要求對(duì)每個(gè)機(jī)型提供一個(gè)zip 格式的刷機(jī)包,該刷機(jī)包可以通過 Recovery 安裝。對(duì)于有的機(jī)型,如果沒有找到可以通過 Recovery 安裝的 zip 包怎么辦,不用擔(dān)心,合要求的 zip 包。下面就教你怎么從里面提取出符首先,假設(shè)現(xiàn)在有一個(gè)機(jī)器叫做 mi,電腦當(dāng)前的目錄是 patchrom:$. build/envsetup.sh mkdir micd mi現(xiàn)在,連接上電腦,并且要確保 USB 調(diào)試在打開狀態(tài)下。$ adb reboot recovery (如果此命令不起作用,那么就
33、手動(dòng)重新啟動(dòng),通過組合按鍵進(jìn)入 Recovery)$ ./tools/ota_from_phone -r (-r 表示在 Recovery 模式下運(yùn)行此工具,也能在正常模式下運(yùn)行,請(qǐng)參照此工具的,從而知道此工具的更完善的用法)此工具將會(huì)生成一個(gè) stockrom.zip 文件和元數(shù)據(jù)目錄,可以用它來適配 MIUI。1.3 adb logcat在第一章介紹過 adb 是一個(gè)非常重要令,其中在機(jī)型適配過程中最常用的就是adb logcat。通過這個(gè)命令可以看到詳細(xì)的 log 信息。每一行的大致格式為:I/ActivityManager( 585):Starting activity:entacti
34、on=android.ent.action.其中第一個(gè)字母表示信息優(yōu)先級(jí)別(E 表示錯(cuò)誤,W 表示警告,I 表示普通信息)。斜杠后的 ActivityManager 表示信息標(biāo)記 tag,通常標(biāo)記表示了打印出相應(yīng)信息的模塊或程序??梢酝ㄟ^ adb logcat tag:* *:S 只顯示相應(yīng) tag 打印的所有信息。括號(hào)中的數(shù)字表示進(jìn)程 ID(),表示程序所在進(jìn)程 ID。冒號(hào)后的句子就是具體的信息說明了,當(dāng)遇到錯(cuò)誤的時(shí)候 adb logcat 會(huì)給出詳細(xì)的錯(cuò)誤信息,通過這些錯(cuò)誤信息去定位錯(cuò)誤。在機(jī)型適配中常用 adb logcat*:E 來查看所有的錯(cuò)誤信息。詳細(xì)的 adb 說明可以參考/gu
35、ide/develo/tools/adb.html。在選定好 ROM 以后,要確保開機(jī)之初,差不多是顯示開機(jī)動(dòng)畫時(shí) adb logcat 命令就能顯示詳細(xì)的 log 信息。如果 adb logcat 只是在桌面程序出現(xiàn)之后才打印信息或者根本就不打印任何信息,適配工作就很難進(jìn)行下去了。如果只是簡(jiǎn)單的修改一些資源的話,那是完全可以的,但是對(duì)于適配 MIUI 來說,的正常運(yùn)行。要求在適配機(jī)型一開始就確保 adb logcat 功能2.修改 boot.img在第二章認(rèn)識(shí) Android中提到過,內(nèi)核 root 的關(guān)鍵是根文件系統(tǒng)中p 文件的兩個(gè)屬性 ro.secure 和 ro.debuggable
36、的值。根文件系統(tǒng)和內(nèi)核一起放在 boot 分區(qū)中,如果核了。能修改 boot 分區(qū)中的這個(gè)文件,那么就可以自己 root 內(nèi)下面介紹一個(gè) root 內(nèi)核的方法,一般來說,某個(gè)機(jī)型的完整刷機(jī)包下有一個(gè) boot.img文件,該文件就是boot 分區(qū)的鏡像文件,安裝刷機(jī)包時(shí),會(huì)使用該文件刷寫boot 分區(qū)給 boot.img 文件定義了一個(gè)標(biāo)準(zhǔn)的格式,如果遵從這個(gè)標(biāo)準(zhǔn)格式,可以用下面的方法來修改它,但是如果不遵從,需要逛詳細(xì)的了解如何修改 boot 分區(qū)。判斷是否遵從有一個(gè)簡(jiǎn)單但是不一定準(zhǔn)確的辦法,如果刷機(jī)包中的文件名為 boot.img,一般來說遵從。如果不是,那么不遵從。比如說三星的 i910
37、0 的刷機(jī)包中這個(gè)文件命名為 zImage(可以在 xda上找到詳細(xì)的修改 zImage 的)。假定在 patchrom 目錄下,給定了一個(gè) boot.img,運(yùn)行如下命令:$ ./tools/unpackbootimg -i boot.img輸出類似如下文字:BOARD_KERNEL_CMDLINE console=ttyDCC0 androidboo BOARD_KERNEL_BASE 00200000BOARD_PAGE_SIZE 4096rdware=如果這些輸出有亂碼,那么可以判定該 boot.img 不遵從標(biāo)準(zhǔn)格式。記下這些參數(shù),接下來還要用到。同時(shí)在 patchrom 目錄下會(huì)看
38、到一個(gè) boot.img-ramdisk.gz 文件,該文件即是根文件系統(tǒng)的壓縮包。還有一個(gè) boot.img-kernel 文件,該文件即是 Linux 文件。$mkdir ramdisk cd ramdiskgzip -dc ./boot.img-ramdisk.gz |cpio -i運(yùn)行這三個(gè)命令后,ramdisk 目錄即為改 p 文件。啟動(dòng)后的根文件系統(tǒng)目錄,用任何編輯器修$ cd .$ ./tools/mkbootfs ./ramdisk | gzip將 ramdisk 目錄重新打包。 ramdisk-new.gz$ ./tools/mkbootimg -cmdline consol
39、e=ttyDCC0 androidboordware=-kernel boot.img-kernel -ramdisk ramdisk-new.gz -base 0 x00200000 size 4096 -o boot-new.img運(yùn)行該命令生成新的 boot.img,-cmdline:該選項(xiàng)為之前打印的 BOARD_KERNEL_CMDLINE-kernel:該選項(xiàng)為 Linux 內(nèi)核文件-ramdisk:該選項(xiàng)為根文件系統(tǒng)壓縮包-base:該選項(xiàng)為之前打印的 BOARD_KERNEL_BASEsize:該選項(xiàng)為之前打印的 BOARD_PAGE_SIZE-o:該選項(xiàng)為輸出文件名3.deo
40、dex當(dāng)把要移植的機(jī)型按照上述步驟刷好了合適的原廠 ROM 后,第一件事就是需要做deodex。對(duì)于 deodex,你只需要理解 odex 是一種優(yōu)化過的 dex 文件就行了,至于怎么優(yōu)化的,這個(gè)不在講述的范圍內(nèi)。Odex 文件是相互依賴的,簡(jiǎn)單地理解就是改了其中一個(gè)文件,其它的 odex 文件就不起作用了。為此,文件變成 dex 文件,讓這些文件可以獨(dú)立修改。須做一個(gè) deodex 操作,就是將 odex一般來說原廠 ROM 發(fā)布時(shí)都是以 odex 文件格式發(fā)布的,如何判斷呢?運(yùn)行如下命令:$ adb sls /system/framework如果看到很多以 odex 結(jié)尾的文件,那么該 R
41、OM 就是做過 odex 的,大家可以用patchrom/tools 目錄下的 deodex.sh來自動(dòng)化的做 deodex 操作。4.Makefile上面已經(jīng)說了怎么選取合適的底包,需要一個(gè) makefile 文件,才能使的patchrom 工作起來。下面是最基本的 patchrom:local-zip-file local-out-zip-filelocal-miui-modifed-apps local-modified-apps local-miui-removed-apps local-phone-appslocal-pre-zip:=stockrom.zip:=:=:=:=:=:=
42、local-zip-miscinclude $(PORT_BUILD)/porting.mklocal-zip-misc:下面系統(tǒng)了。來解釋一下這個(gè)文件的各個(gè)定義,理解了這些定義,你能清楚的看透整個(gè)創(chuàng)建local-zip-file:這個(gè) ROM 就是上面尋找的合適的底包,必須對(duì)應(yīng)各個(gè)機(jī)型local-out-zip-file:當(dāng)你運(yùn)行”make zipfile”以后,輸出的 ROM 的名字local-miui-modified-apps:在 patchrom/build/miuiapps.mk 中列出了所有的 miuiapps,這個(gè)變量定義了哪些是修改過的 miui apps。local-mod
43、ified-apps:這個(gè)變量定義了哪些 apps 是的在 local-zip-file 中修改過local-miui-removed-apps:通常不是所有的 miui apps 都是適合的設(shè)備的。這個(gè)定義了哪些 miui apps 是不需要的。local-phone-apps:這個(gè)定義了需要從 local-zip-file 里面去除的 apps。正如我們所看到的這個(gè)定義給 miui apps 設(shè)置了,給 stockrom 里面的 apps 設(shè)置了白。需要的就是需要在 stockrom 里面留下來的 apps。local-zip-misc:這個(gè)目標(biāo)允許根據(jù)自己的設(shè)備的情況,做一些自定義。第四
44、章 反編譯這一章來詳細(xì)的看看反編譯,想要修改一個(gè)系統(tǒng)自帶的應(yīng)用程序和它的代碼,在沒有源碼的情況下,就不得不用反編譯來修改。和很多書籍一樣,為了向經(jīng)典的”o,World”致敬,也從一個(gè)簡(jiǎn)單的程序開始o(jì)Activity.apk。當(dāng)你把這個(gè) APK 安裝到上運(yùn)行后,在屏幕上面就顯示一行文字”o,World!”1.反編譯假定在 patchrom 目錄下:$ ./tools/apktool doActivity.apk這條命令運(yùn)行完后,在當(dāng)前目錄下會(huì)生成一個(gè)名為該目錄的結(jié)構(gòu)為(名稱后跟/表示這是一個(gè)目錄):oActivity/|AndroidManifest.xml|apktool.ymloActivi
45、ty 的目錄。|-res/|smali/apktool.yml 是 apktool 生成的一個(gè)配置文件,基本上你不需要修改這個(gè)文件。下面的逐個(gè)介紹剩下的 AndroidManifest.xml 文件和 res,smali 目錄。章節(jié)2.AndroidManifest.xml要想完全理解這個(gè)文件,你得對(duì) Android 的機(jī)制非常清楚。幸好修改一個(gè)APK 的時(shí)候基本上不修改這個(gè)文件。這里幫助你有一個(gè)大致的了解。Android 安裝程序一般叫 apk 文件(apk 是 Android Package 的縮寫,表示 Android 安裝包)。一般來說,程序都會(huì)有一個(gè)或者多個(gè) Activity,Act
46、ivity 是什么呢?從概念說它是一個(gè)和用戶交互的窗口,你每天使用 Android的時(shí)候基本上你打交道的每個(gè)界面都是一個(gè) Activity。AndroidManifest.xml 是一個(gè) xml 格式的文件,就像你去超市買東西打印出來的一個(gè)購(gòu)物,AndroidMainfest.xml 也起著一個(gè)的作用,它告訴系統(tǒng),我有這些 Activity 。(實(shí)際情況遠(yuǎn)比這個(gè)復(fù)雜得多,想學(xué) Android 編程的通信請(qǐng)看這個(gè)/guide/index.html)。具體到ent.category.LAUNCHER”/其中有一行,包含這一行的 Activity 會(huì)顯示在桌面上,就是說你可以通過桌面顯示的圖標(biāo)啟動(dòng)這
47、個(gè) Activity。里面還有 android:label=”string/app_name” android:icon=”drawable/ic_launcher_o”。這兩個(gè)屬性是做什么的呢,android:label 表示程序顯示在桌面上的名字,android:icon 表示程序顯示在桌面上的圖標(biāo)。如果想要改顯示的名字和圖標(biāo),修改其后的兩個(gè)資源,如何修改資源,下一節(jié)詳細(xì)介紹。3.資源res 目錄下放置了程序所需要的所有資源。資源是什么呢?一般來說,一個(gè)圖形用戶界面(GUI)程序總是會(huì)使用一些,或者顯示的文字的大小和顏色等,或者界面的布局,比如顯示的界面上面是文字,下面是兩個(gè)按鈕等等。這些
48、程序的一個(gè)重要特點(diǎn)就是用戶界面和代碼邏輯的分離。當(dāng)需要替換或者簡(jiǎn)單修改界面布局的時(shí)候,不需要改變代碼。而 Android 程序會(huì)將這些代碼中需要用到的文件都放在 res 目錄下面,稱之為資源??梢钥吹?res 目錄的內(nèi)容為:res/|drawable-hdpi/|ic_launcher_|layout/o. g|values/o_activity.xml|ids.xml|public.xml|strings.xml對(duì)于oActivity 來說,res 目錄下有三個(gè)子目錄 drawable-hdpi,layout,values。oActivity 比較簡(jiǎn)單,因此 res 下內(nèi)容不多,但是一個(gè)復(fù)雜
49、的程序 res 目錄下內(nèi)容由于相應(yīng)的也會(huì)比較多,但是基本原理都是一樣的。res 下面的子目錄基本上是按照資源類型來分類組織的,以 drawable 開頭的表示資源,大家可能會(huì)看到 drawable-xhdrawable-hdrawable-mdrawable-ldpi等,這些 xhdpi,hdpi,mdpi,ldpi 分別表示分辨率的不同級(jí)別,會(huì)根據(jù)不同的屏幕分辨率選擇不同的點(diǎn),一般替換。要想替換,替換這些目錄下的就可以了。(替換比這稍復(fù)雜一,最好保持和原兼容,比如說色系,尺寸以及點(diǎn) 9的一些參數(shù)等)。以 layout 開頭的表示布局文件,程序的界面。anim 子目錄存放程序使用到的動(dòng)畫,xm
50、l 開頭的目錄存放程序用到的一些 xml 文件等。values 開頭的目錄下面存放一些稱之為基本元素的定義,比如說 colors.xml 給出顏色的定義,dimens.xml 給出一些大小的定義。Strings.xml 是一些字符串的定義。看oActivity 的 strings.xml 文件。看?Xml vero,World!oWorld其中的以string 開頭表示這是一個(gè)字符串,name 是給這個(gè)資源起的一個(gè)名字,后面的字符單表示這個(gè)字符串的值。Android 的資源大致按這種形式來組織的,先將資源分成幾種類型,然后每一種類型的所有資源取一個(gè)名字,這個(gè)名字對(duì)應(yīng)了這個(gè)資源的值/內(nèi)容。一般修
51、改資源,通常情況下是修改 或者漢化。漢化比較簡(jiǎn)單, values/string.xml 文件存放程序用到的所有英文字符串值。要漢化,首先在 values 下建立一個(gè)目錄 翻譯成中文。?xml ver目錄下,并將文件內(nèi)容改為:你好,世界!你好世界現(xiàn)在需要把修改后的文件再編譯回 apk 文件,運(yùn)行命令如下:$ ./tools/apktool b這條命令表示編譯oActivityoActivity.apkoActivity 目錄的內(nèi)容,輸出文件為oActivity.apk,如果你不想覆蓋原有的文件,樂意換一個(gè)名字或者放在另一個(gè)目錄下面。接下來需要對(duì)生成的 APK 進(jìn)行簽名,$ ./tools/sig
52、n.sh$ adb install -roActivity.apkoActivity.apk.signed.aligned注意最后一條命令,如果你失敗了,如果你不是用提供的oActivity 做實(shí)驗(yàn)的話,會(huì)發(fā)生簽名不一致的錯(cuò)誤,這個(gè)時(shí)候先卸載原來的,再安裝。運(yùn)行看看,現(xiàn)在顯示在你面前的就是“你好,世界!”漢化成功了,是的!漢化就是那么的簡(jiǎn)單。如果你只想停留在漢化或者替換的這個(gè)階段,從這里開始以后的文章就不用在看了。如果你沒有 Android 編程基礎(chǔ),從這里開始以后的文章也不用看了。到底發(fā)生了什么魔法,為什么這樣替換一些或者改字符串就能改變程序最終運(yùn)行的,想要理解這個(gè),就得大致的了解一下資源的
53、編譯過程。首先看看 values目錄下的一個(gè)有意思的文件 publics.xml,他的內(nèi)容如下:?xml verpublic type=”layout”name=”o_activity_text_text”id=”0 x7f040000”每一行的 id 后面都有一個(gè)看起來很奇怪的數(shù)字,這些數(shù)字是干什么的呢?Android 下有一個(gè)資源編譯器會(huì)編譯 res 目錄下的所有文件,它為每一個(gè)資源名字分配一個(gè)數(shù)字標(biāo)示符,這個(gè)標(biāo)示符分成 3 個(gè)部分,最前面的 1 個(gè)字節(jié)表示包名,所有的 apk 這個(gè)字節(jié)都是 7f。表示這些資 源是 非共享 的, 其它 APK不 到。所 有那 些可以 共享 的資 源放 在s
54、ystem/framework/framework-res.apk 里面。System/framework 往往還有其它共享的資源包。這些共享的資源包前面的 1 個(gè)字節(jié)從 0 x1 開始,一次增加。中間的一個(gè)字節(jié)表示資源的類型,每一個(gè)類型的數(shù)字標(biāo)示符是不一樣的,最后的 2 個(gè)字節(jié)是資源的序號(hào),類型的資源序號(hào)從 0 一次往上遞增。一般來說,資源 id 是由資源編譯器(aapt)自動(dòng)產(chǎn)生的,但是定義在 publics.xml 中的值告訴編譯器,你必須為這個(gè) id 使用這個(gè)值。Apktool 會(huì)為所有的資源名稱定義這個(gè)值在 publics.xml 里,這樣可以保證替換資源后資源的 id 不會(huì)變化。為
55、什么資源的 id 這么重要,如果變了,會(huì)怎么樣呢,這得結(jié)合代碼來理解。在 Java代碼里通常這樣資源,比如 R.string.app_name。這個(gè) Java 代碼經(jīng)過編譯后,這條引用直接變成了資源 id,即 0 x7f040001,所以你在下面反編譯后的 smali 代碼里面是看不到 R.string.app_name 這個(gè)東西的,只能看到 0 x7f040001.資源編譯器會(huì)產(chǎn)生一個(gè)查找表,對(duì)于每個(gè) id,查找表中保存了這個(gè) id 對(duì)于的名字和值(如果是文件,則為文件所在路徑)。程序在運(yùn)行的時(shí)候,會(huì)根據(jù) id 去查詢這個(gè)查找表找到對(duì)應(yīng)的資源的值或者文件。最 后 說 一 句 , 資 源ID真
56、 的 非 常 重 要 , 運(yùn) 行adbpull/system/framework/framework-res.apk 反編譯這個(gè)文件,好好的咀嚼一下這一節(jié)的內(nèi)容吧。4.smali終于迎來了最重要的部分了-smali 目錄,smali 目錄存放的是反編譯后的 Java代碼,文件名以 smali 結(jié)尾,故稱作 smali 文件。這些代碼比一般的 Java 代碼可讀性差很多,但是和傳統(tǒng)的 x86 或者其他體系結(jié)構(gòu)下的匯編文件相比較的話,那還是好讀了很多。雖然有工具可以直接把這些反編譯成 java 代碼,但是好不了很多,smali 文件。還是直接修改來看一下反編譯后的 smali 目錄下的oActiv
57、ity.smali 文件,和 java 組織源碼的方式一樣,smali 目錄下的文件也是按照文件包的包名結(jié)構(gòu)來組織目錄結(jié)構(gòu)的,文件的內(nèi)容如下:.class public Lcom/exle/android/oactivity/oActivity;.super Landroid/app/Activity.source “oActivity.java”# direct methods.method public constructor()V.locals 0.prologue.line 27invoke-direct p0,Landroid/app/Activity;-()Vreturn-void
58、.end method# virtual methods.method public onCrea.locals 2android/os/Bundle;)V.parameter”savedInstane”.prologue.line 33invole-super p0,p1,Landroid/app/Activity;-onCreaandroid/os/Bundle;)V.line 37const/high16 v1,0 x7f03invoke-virtualp0,v1,Lcom/exle/android/oactivity/oActivity;-setContentView(I)V.line
59、 38const/high16 v1,0 x7f05invoke-virtualp0,v1,Lcom/exle/android/oactivity/oActivity;-findViewById(I)Landroid/view/View;move-result-object v0check-cast v0,Landroid/widget/TextView;.line 39.local v0.txtView:Landroid/widget/TextView; const/high16 v1,0 x7f04invoke-virtualv0,v1,Landroid/widget/TextView;-
60、setText(I)V.line 40 return-viod.end method文件中的以#開頭的文字表示注釋,以.開頭的叫做 annoions,其中的.line 表示對(duì)于的源代碼的行號(hào),這個(gè)對(duì)調(diào)試很重要。.method 和.end method 表示一個(gè)方法定義的開始和結(jié)束。Smali 文件中的重要指定的功能,請(qǐng)參照本文檔的副頁,里面有詳細(xì)的介紹。有過java 編程基礎(chǔ)的很容易理解這些指令。其中.line 39 的代碼對(duì)應(yīng)的源代碼是txtView.setText(R.string.o_activity_text_text)現(xiàn)在想將這行代碼改成 textView.setText(“Happ
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2024年職業(yè)院校技能導(dǎo)游專業(yè)(旅游法律法規(guī))知識(shí)試題與答案
- 2025年安徽省馬鞍山市考研專業(yè)綜合預(yù)測(cè)試題含答案
- 遼寧省沈陽市遼中區(qū)2024-2025學(xué)年七年級(jí)下學(xué)期期末語文試題(解析版)
- 信息技術(shù)ps試題及答案
- 廣東省梅州市五華縣2024-2025學(xué)年八年級(jí)上學(xué)期11月期中物理試題(教師版)
- 2025豪華公寓房屋買賣合同
- 2025如何挑選適合企業(yè)的合同管理系統(tǒng)
- 2025商店轉(zhuǎn)讓合同協(xié)議書
- 2025酒店餐飲服務(wù)承包合同樣本
- 搭建創(chuàng)新的橋梁課件
- 輔助角公式練習(xí)題
- GB/T 7631.8-1990潤(rùn)滑劑和有關(guān)產(chǎn)品(L類)的分類第8部分:X組(潤(rùn)滑脂)
- GB/T 40333-2021真空計(jì)四極質(zhì)譜儀的定義與規(guī)范
- GB/T 35778-2017企業(yè)標(biāo)準(zhǔn)化工作指南
- 羽毛球校本教材
- GB/T 15601-2013管法蘭用金屬包覆墊片
- GB/T 12325-2008電能質(zhì)量供電電壓偏差
- 汽輪機(jī)原理-凝汽器課件
- 二年級(jí)下冊(cè)認(rèn)識(shí)方向練習(xí)題
- 檢驗(yàn)報(bào)告(風(fēng)機(jī))
- 鼻骨及眼眶骨折的CT診斷課件
評(píng)論
0/150
提交評(píng)論