這篇文件多是你看過的寫的最詳細的關於SystemUI如何導入AS的文章了~java
下面要講的,是我若是一步步將SystemUI導入到AndroidStudio的。android
(備註:本文所講內容的開發環境 -> Android版本9.0 AndroidStudio 3.4 gradle插件版本 3.5)shell
修改系統相關模塊的代碼,若是是小的修改還好,若是是須要改動比較多,那能將源碼導入到AndroidStudio來修改是最好不過的了,修改效率會提升不少。微信
這篇文件針對下面幾點展開:app
1、下載SystemUI源碼; 2、將SystemUI代碼導入Eclipse,在Eclipse中導出工程gradle文件; 3、將SystemUI代碼導入AndroidStudio; 4、導入過程遇到的問題及解決;
講述重點會放在第四部分,遇到的問題及解決。eclipse
SystemUI的代碼,直接在Android源碼中下載到本地來便可,在framewrok/bace/packages/目錄下。async
咱們的終極目標是把SystemUI的代碼導入到AndroidStudio,之因此先把工程導入到Eclipse,是藉助eclipse幫咱們生成工程須要的gradle文件,AndroidStudio的工程是依靠gradle來構建,有了這個gradle文件,下一步就能夠導入AndroidStudio了。ide
導出gradle文件也很簡單,選擇咱們的工程,右擊,選擇Export,選擇Generate Gralde build files,而後一直next便可。學習
有了上面第二部分的導出的gralde文件,就能夠打開AndroidStuido,找到工程目錄,導入工程便可。gradle
導入工程後,會有報錯,那確定是正常的,否則就不會有第四部分的內容了。這裏注意下gradle的版本,eclipse中導出的gradle版本可能會是比較舊的,這個須要根據本身的須要和提示的錯誤修改下。我是把gradle插件版本修改爲了3.5.0
將Android源碼模塊的代碼導入到AndroidStudio之因此麻煩,就是源碼模塊的代碼可能會涉及到引用的相關資源比較多,所謂的資源,就是jar或者系統其它的一些類。
1)查看Android.mk涉及用到哪些資源
源碼的編譯,是依靠.mk來進行編譯,查看Android.mk,能幫咱們大體瞭解下這個項目會用到哪些外部資源。
LOCAL_STATIC_ANDROID_LIBRARIES 裏面的,就是須要打包編譯進apk的jar包 ---------------- LOCAL_STATIC_ANDROID_LIBRARIES := \ SystemUIPluginLib \ SystemUISharedLib \ android-support-car \ android-support-v4 \ android-support-v7-recyclerview \ android-support-v7-preference \ android-support-v7-appcompat \ android-support-v7-mediarouter \ android-support-v7-palette \ android-support-v14-preference \ android-support-v17-leanback \ android-slices-core \ android-slices-view \ android-slices-builders \ android-arch-core-runtime \ android-arch-lifecycle-extensions \
LOCAL_JAVA_LIBRARIES 裏面的jar,是隻在編譯的時候引用便可,不須要打包進apk,這些jar是系統自己的jar ----------------- LOCAL_JAVA_LIBRARIES := telephony-ext \ telephony-common \ android.car \ ims-common
2) 將須要的jar包導入到工程
查看了Android.mk的內容,咱們接下來就須要把相關的jar包導入到工程。好了,那這些jar包如何找呢。
從Android.mk的內容咱們看到,有2類jar包,一類是須要打包進apk的,一類是隻須要編譯階段引用的。那咱們找包的時候,也分2種狀況來。
LOCAL_STATIC_ANDROID_LIBRARIES 裏面引用到的jar,能夠在這個路徑下找到對應的jar包:
這裏列出的是androidx.annotation_annotation.jar的路徑, 其它jar包也是相似方式查找,在./out/soong/.intermediates/prebuilts/sdk/current目錄下
./out/soong/.intermediates/prebuilts/sdk/current/androidx/androidx.annotation_annotation/ android_common/turbine-combined/androidx.annotation_annotation.jar
LOCAL_JAVA_LIBRARIES 裏面引用到的jar,是在out/target/project/......./system/framework/目錄下能夠找到。
3) 問題:導入的不一樣jar包,包含了相同的內容
經過上面的方式找到的jar,發現有個問題,就是不一樣的jar包,基本都包含了相同的內容。編譯的時候會報Duplicate class 的錯誤。
從下面這張圖,咱們能夠看到,導入的3個不一樣的jar,都包含了相同的android.arch.*、android.support.*等等這些類,這個就致使編譯直接報類重複了。 這個問題,在網上找了不少的解決方法,基本都是說導入jar包的時候,採用exclude字段,把重複的group或者module移除掉,不過我試的時候,直接提示gradle DSL 沒有exclude。
我一直覺的多是我找的jar包不對,不該該都包含有相同內容的,若是有知道緣由的,能夠和我說下,很是感謝!
######4)修改jar包,將jar包重複內容刪除,再從新生成jar包
後面是沒其它頭緒了,就試着把jar包重複的內容刪除,再從新合成jar包。
具體作法就是,把jar包後綴修改爲zip,而後解壓,刪除重複的內容(這裏刪除內容,我只是刪除了相關的重複類,原本的META-INF文件夾沒有動)後,再經過jar cvf 命令,從新生成jar。
這個過程,就是不停的刪除重複內容,而後再導出,再編譯。
5)問題: More than one file was found異常
編譯的時候,還遇到了下面的問題,說是META-INF/*** 內容有多個地方都有, 這個問題,我以爲的可能和上面第4點的內容有關, 刪除重複包的時候,我仍是保留原來的META-INF文件夾沒有動。
More than one file was found with OS independent path 'META-INF/androidx.legacy_legacy-support-core-ui.version'
這個問題能夠經過添加 packagingOptions {...}來進行解決,在工程的build.gradle 文件中添加,下面就是我添加的,提示那個有多的,就加下。
android { compileSdkVersion 28 defaultConfig { applicationId "com.android.systemui" minSdkVersion 28 targetSdkVersion 28 versionCode 29 } packagingOptions { exclude 'META-INF/androidx.mediarouter_mediarouter.version' exclude 'META-INF/androidx.localbroadcastmanager_localbroadcastmanager.version' exclude 'META-INF/androidx.lifecycle_lifecycle-livedata-core.version' exclude 'META-INF/androidx.appcompat_appcompat.version' exclude 'META-INF/androidx.swiperefreshlayout_swiperefreshlayout.version' exclude 'META-INF/androidx.cursoradapter_cursoradapter.version' exclude 'META-INF/androidx.media_media.version' exclude 'META-INF/androidx.drawerlayout_drawerlayout.version' exclude 'META-INF/androidx.print_print.version' exclude 'META-INF/androidx.versionedparcelable_versionedparcelable.version' exclude 'META-INF/androidx.interpolator_interpolator.version' exclude 'META-INF/androidx.palette_palette.version' exclude 'META-INF/androidx.fragment_fragment.version' exclude 'META-INF/androidx.customview_customview.version' exclude 'META-INF/androidx.documentfile_documentfile.version' exclude 'META-INF/androidx.vectordrawable_vectordrawable.version' exclude 'META-INF/androidx.legacy_legacy-support-core-utils.version' exclude 'META-INF/androidx.loader_loader.version' exclude 'META-INF/androidx.lifecycle_lifecycle-runtime.version' exclude 'META-INF/androidx.viewpager_viewpager.version' exclude 'META-INF/androidx.asynclayoutinflater_asynclayoutinflater.version' exclude 'META-INF/androidx.lifecycle_lifecycle-viewmodel.version' exclude 'META-INF/androidx.recyclerview_recyclerview.version' exclude 'META-INF/androidx.core_core.version' exclude 'META-INF/androidx.arch.core_core-runtime.version' exclude 'META-INF/androidx.vectordrawable_vectordrawable-animated.version' exclude 'META-INF/androidx.slidingpanelayout_slidingpanelayout.version' exclude 'META-INF/androidx.slice_slice-core.version' exclude 'META-INF/androidx.coordinatorlayout_coordinatorlayout.version' exclude 'META-INF/androidx.legacy_legacy-support-core-ui.version' } }
6) 問題:Duplicate class,support包合androidx包引用有衝突 錯誤提示:
Duplicate class android.support.v4.app.INotificationSideChannel found in modules android-arch-lifecycle-extensions.jar (android-arch-lifecycle-extensions.jar) and classes.jar (androidx.core:core:1.1.0-beta01)
解決方法: 在gradle.properties中添加啓用androidx支持,gradle.proerties文件原本是沒有的,沒有的話,就本身建立個
android.useAndroidX=true
7) 問題:adb push apk進入,重啓,提示權限錯誤
android.view.InflateException: Binary XML file line #87: uid=10014 needs permission android.permission.READ_CONTACTS to read lock_screen_owner_info_enabled for user 0
錯誤提示,須要android.permission.READ_CONTACTS 權限,這個權限在manifest中是有申請的了。後面參考了https://blog.csdn.net/grindstone_fos/article/details/53924295 提供的方法解決了。
方法就是:執行adb命名,給與相應權限。我是遇到有2個權限須要經過下面方式來執行下才行。
adb shell pm grant "com.android.systemui" "android.permission.READ_CONTACTS" adb shell pm grant "com.android.systemui" "android.permission.READ_EXTERNAL_STORAGE"
8)問題: 提示資源找不到
好不容易解決了上面的一堆的問題,下面是接着報了個資源找不到的問題。這個沒查到是啥緣由,後面是把調用到的代碼暫時屏蔽了。
Line 1145: 12-28 14:27:52.209 E/AndroidRuntime( 2422): FATAL EXCEPTION: main Line 1146: 12-28 14:27:52.209 E/AndroidRuntime( 2422): Process: com.android.systemui, PID: 2422 Line 1147: 12-28 14:27:52.209 E/AndroidRuntime( 2422): android.content.res.Resources$NotFoundException: Resource ID #0x0 Line 1148: 12-28 14:27:52.209 E/AndroidRuntime( 2422): at android.content.res.ResourcesImpl.getValue(ResourcesImpl.java:216) Line 1149: 12-28 14:27:52.209 E/AndroidRuntime( 2422): at android.content.res.Resources.getDimensionPixelSize(Resources.java:727) Line 1150: 12-28 14:27:52.209 E/AndroidRuntime( 2422): at androidx.slice.widget.ListContent.<init>(ListContent.java:103) Line 1151: 12-28 14:27:52.209 E/AndroidRuntime( 2422): at androidx.slice.widget.ListContent.<init>(ListContent.java:88) Line 1152: 12-28 14:27:52.209 E/AndroidRuntime( 2422): at com.android.keyguard.KeyguardSliceView.showSlice(KeyguardSliceView.java:161) Line 1153: 12-28 14:27:52.209 E/AndroidRuntime( 2422): at com.android.keyguard.KeyguardSliceView.onChanged(KeyguardSliceView.java:343)
9)問題:AndroidRunTime 空指針異常
OverviewProxyService.java 中報了個空指針異常,獲取到的 mRecentsComponentName 爲空,也就是經過mContext.getString(com.android.internal.R.string.config_recentsComponentName)無法獲取到對應的資源,後面是直接改爲將string的內容寫進去了。
導這個工程花了比較多的時間,還好沒有放棄~~
本人從事Android Camera相關開發已有5年
目前在深圳上班
歡迎你們關注個人微信公衆號「小馳筆記」
你們一塊兒學習交流
------- 2020.02.04 21:31 立春