本文適用于有一定Android源碼編譯能力的開(kāi)發(fā)者,對(duì)AOSP沒(méi)有什么概念的同學(xué)可以參考涅槃1992發(fā)表的文章:自己動(dòng)手編譯Android源碼(超詳細(xì)),正如作者所說(shuō),超詳細(xì),也很簡(jiǎn)單.
引入
我之前一直從事App開(kāi)發(fā),換工作后公司正在研發(fā)一款類似百度小度的帶屏智能硬件,所以需要定制Android系統(tǒng).花了一個(gè)月熟悉Linux開(kāi)發(fā)環(huán)境和Android8.1的源碼結(jié)構(gòu)后,我接下了相冊(cè)Gallery2和桌面Launcher3的定制工作.AOSP中Gallery2和Launcher3的源碼結(jié)構(gòu)和普通App開(kāi)發(fā)目錄結(jié)構(gòu)并不一樣,直接導(dǎo)入到Android Studio中并不能運(yùn)行,只能當(dāng)做一個(gè)文檔查看器.網(wǎng)上也有文章講到可以先將源碼導(dǎo)入Eclipse再導(dǎo)入Android Studio的這種曲線救國(guó)的方法,但是,Eclipse ? excuse me ? 下面就拿Gallery2作例子,步步講解怎樣將Android Gallery2源碼導(dǎo)入Android Studio中并一鍵運(yùn)行起來(lái).
環(huán)境
AOSP版本:Android 8.1 ,
Ubuntu版本:18.04.1 LTS
流程
將AOSP源碼中的Gallery2直接導(dǎo)入到Android Studio中的目錄結(jié)構(gòu)如下,這顯然不是普通App開(kāi)發(fā)的目錄結(jié)構(gòu).

新建一個(gè)Gallery2_blog工程,包名和原生Gallery2一樣都是com.android.gallery3d,工程地址就用/home/majiheng/majh/workspace/Gallery2_blog,最低api我設(shè)置成了21也就是Android L系統(tǒng),然后一路next就行了,如下圖所示:

下面才是普通App開(kāi)發(fā)的目錄結(jié)構(gòu):

回過(guò)頭看"圖1",其中g(shù)allerycommon,src,src_pd這三個(gè)文件夾下是所有Gallery2所涉及到的源碼,我不太明白谷歌的工程師為什么這樣組織結(jié)構(gòu),有明白的同學(xué)可以留言或私信我.jni,jni_jpegstream是Gallery2用到的所有so文件的源代碼,也就是說(shuō)這些文件你是可以修改的,然后再打包成.so文件,當(dāng)然這兩個(gè)文件夾暫時(shí)忽略,因?yàn)檫@里沒(méi)有涉及到修改c文件的需求.res文件夾包含了Gallery2所有的資源文件例如圖片和布局.AndroidManifest.xml不用管,里面內(nèi)容暫時(shí)不需要修改.
先把gallerycommon,src,src_pd這三個(gè)文件夾中的所有文件按照包名com.android.gallery3d結(jié)構(gòu)復(fù)制到新創(chuàng)建的Gallery2_blog工程中,同時(shí)將清單文件AndroidManifest.xml里的內(nèi)容也無(wú)損復(fù)制過(guò)來(lái),結(jié)果如下:

接下來(lái)把res文件夾里的資源全部拷貝到Gallery2_blog工程中來(lái),可以看到,原生相冊(cè)Gallery2基本適配了市面上所有的Android設(shè)備,所以各種版本的drawable,layout,mipmap,values很多,由于圖片太長(zhǎng),部分截圖如下:

由于相冊(cè)Gallery2涉及到mp4和gif的播放,所以需要引入.so和.jar文件,那到底該引入哪些呢?先說(shuō).so文件,到編譯過(guò)的AOSP源碼中out/target/product/generic/system/app/Gallery2/lib/arm64目錄下查看,可以看到3個(gè).so文件分別是:libjni_eglfence.so,libjni_filtershow_filters.so和libjni_jpegstream.so.但千萬(wàn)要注意的是:這3個(gè)文件并不是真正的文件,而是軟連接!在該目錄下打開(kāi)命令窗口輸入ll命令后如下:

實(shí)際上這3個(gè)真正的.so文件在目錄out/target/product/generic/system/libs中,將這3個(gè).so文件復(fù)制到Gallery2_blog中的src/jniLibs/armeabi-v7a目錄中,如下圖所示:

先不說(shuō)需要哪些.jar包,我們先試著運(yùn)行下,看看報(bào)什么錯(cuò).第一個(gè)錯(cuò)誤如下:

實(shí)際上還有一大堆錯(cuò)誤和上面一樣,都是某個(gè)在Strings.xml文件中定義的字符串出現(xiàn)了兩次,并且這些字符串都沒(méi)有被使用,這里為了簡(jiǎn)便,把除了中英文所有國(guó)際化的values文件夾都刪除了,然后再次試著運(yùn)行,出現(xiàn)如下錯(cuò)誤:

出現(xiàn)以上錯(cuò)誤說(shuō)明編譯器提醒沒(méi)有導(dǎo)入相應(yīng)的jar包,錯(cuò)誤詳情如下幾張圖所示:





從上面的錯(cuò)誤可以總結(jié)出來(lái)缺少了junit,xmp,mp4parser,apache,v13總共5個(gè)jar包,這5個(gè)jar包怎么找?網(wǎng)友可能會(huì)說(shuō):這個(gè)簡(jiǎn)單,在gradle里面直接配置下載就行,這個(gè)也可以,不過(guò)還可以在AOSP源碼里面找,具體路徑是out/target/common/obj/JAVA_LIBRARIES,直接在該目錄下搜索junit,xmp,mp4parser,apache,v13就可以找到相應(yīng)的文件夾,比方說(shuō)搜索junit,搜索結(jié)果是junit_intermediates文件夾下的classes.jar.然后把這5個(gè)jar包全部放到Gallery2_blog工程下的libs文件夾中,記得右鍵Add As Library...
試著再次運(yùn)行,出現(xiàn)如下錯(cuò)誤:

上述錯(cuò)誤定位到清單文件AndroidManifest.xml文件,無(wú)法識(shí)別如下兩個(gè)授權(quán)信息,可以暫時(shí)將這兩個(gè)授權(quán)注釋掉,具體為什么會(huì)出現(xiàn)這兩個(gè)授權(quán)信息,在Android中的權(quán)限管理(基于Permission ProtectionLevel)一文中有詳細(xì)講解:

再次試著運(yùn)行一下,出現(xiàn)如下一堆類似錯(cuò)誤(此時(shí)感覺(jué)錯(cuò)誤綿綿不絕):

點(diǎn)進(jìn)去一個(gè)文件進(jìn)行查看,發(fā)現(xiàn)里面的ScriptC_convolve3x3這個(gè)類并沒(méi)有生成,如下圖所示:

轉(zhuǎn)到app/build/generated/res/rs和app/build/generated/source/rs目錄下,可以看到這兩個(gè)目錄下并沒(méi)有生成想對(duì)應(yīng)的native代碼,如下圖所示:

正確生成rs的話,截圖應(yīng)該如下:

怎樣生成rs?先在src/main目錄下新建一個(gè)rs文件夾,然后到/src/main/java/com/android/gallery3d/filtershow/filters目錄下拷貝后綴為.rs的convolve3x3.rs,grad.rs,grey.rs,saturation.rs,vignette.rs這5個(gè)文件到剛剛創(chuàng)建的rs文件夾中.然后刪除app下的build文件夾,再次試著運(yùn)行出現(xiàn)如下錯(cuò)誤(稍許崩潰中...):

上面這個(gè)錯(cuò)誤是因?yàn)関7包和v4包出現(xiàn)沖突所致,到app下的gradle中注釋掉implementation 'com.android.support:appcompat-v7:28.0.0'再次試著運(yùn)行下,app正常啟動(dòng)了,最后附一張Gallery2的圖片:


最后附上項(xiàng)目git地址:
https://github.com/afterschoolkido/Gallery2_AOSP_AndroidStudio_Version
歡迎star & fork~
文章推薦:
5分鐘適配Android P和Android 8.0劉海屏,可能全網(wǎng)最全總結(jié)
Android Retrofit Http加密(無(wú)證書加密)
Android WebSocket加密