客觀來說,9.0兼容好像問題不是很大,很多的APP一點問題都沒有,但是有些比較舊的APP就問題比較多了,下面簡單寫一下解決方法,本文純屬筆記,方便以後查看。
網絡問題:
問題一
應對9.0 版本的網絡明暗流量問題
設置一下 application (清單文件裏面)
<application
android:usesCleartextTraffic="true"
>
問題二
引用httpclient的報錯
java.lang.NoClassDefFoundError: Failed resolution of: Lorg/apache/commons/logging/LogFactory;
Caused by: java.lang.ClassNotFoundException: Didn't find class "org.apache.commons.logging.LogFactory" on path: DexPathList[[zip file "/data/app/com.inno.nestlesuper- oPFXtK6GZQsOCWb8lvmj2g==/base.apk"],nativeLibraryDirectories= [/data/app/com.inno.nestlesuper-oPFXtK6GZQsOCWb8lvmj2g==/lib/arm, /data/app/com.inno.nestlesuper-oPFXtK6GZQsOCWb8lvmj2g==/base.apk!/lib/armeabi, /system/lib, /vendor/lib]]
主要問題是 9.0版本谷歌不支持這兩個網絡包了需要自己導進去支持來規避兼容問題。
api files('libs/httpclient-4.3.6.jar')
api files('libs/httpcore-4.3.2.jar')
然後 解決方法如下:
下載導入一個commons-logging的jar包
api files('libs/commons-logging-1.2.jar')
自此網絡問題解決。
當然使用jar畢竟麻煩,時不時更新就需要改動,在此用新的方法:
在AndroidManifest.xml下的<application>節點加入以下相關依賴(如果項目繼續使用Apache的httpclient),這是因爲httpclient在Android6.0就已經被廢棄了,如果不想大變動我們可以將這個庫強制依賴進來,避免報錯。
<uses-library
android:name="org.apache.http.legacy"
android:required="false" />
同時在app目錄下build.gradle的android節點加入httpclient依賴:
useLibrary 'org.apache.http.legacy'
Android9.0官方要求中,禁止傳輸接收沒加密的數據,也就是說對網絡數據傳輸這一塊做了限制,我們需要在AndroidManifest.xml中的<application>節點內加入網絡安全配置:
<application
android:networkSecurityConfig="@xml/network_security_config"
tools:replace="android:theme,android:allowBackup">
其中network_security_config.xml在xml目錄如下:
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config cleartextTrafficPermitted="true" />
</network-security-config>
依賴問題
我們升級SDK編譯版本和目標版本爲28時,我們需要改動相應的依賴版本:
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support:support-v4:28.0.0'
衝突Program type already present
下面是一個項目build.gradle中的依賴,我們簡單做一下分類
網絡相關
okhttp
retrofit
http-legacy
常用類庫
rxpermission(權限監測)
leakcanary(內存泄漏)
BaseRecycleViewAdapterHelper(star較多的Adapter)
rxjava2
smartRefreshLayout(刷新)
不常用
bmob(消息推送)
jsoup(html解析器)
異常
當我們運行時,會發生異常
查看異常
自帶工具查看
如果你覺得標識的不太清晰,可以點擊如圖所示圖標,展開信息
通過指令將異常保存
gradlew build --stacktrace > logs.txt 2>logErrors.txt
編譯前,請確認gradle環境變量已配置,關於build Task請查看Gradle總結。
通過上述指令,將信息分別保存到上述文件中(默認項目根目錄):
logs.txt:編譯過程信息
logErrors.txt:異常信息
logs、logErrors信息如下:
分析異常
在logErrors中看到Program type already present: okio.AsyncTimeout$1,如何查看是否有多個的Okio文件呢?
通過搜索欄查看
雙擊Shift,在搜索框中輸入Okio,可以看到有2條okio的信息
在Terminal中輸入指令
gradlew -q app:dependencies
在External Libraries中查看對應依賴
解決
Group與module的區別
要解決上述問題,首先要明白Group與module的區別,然而搜索了一遍,好像網上沒有給出比較清晰的解釋,而這些又是解決依賴衝突這些問題首先要明白的問題,本人在摸索中,稍微總結了一下(如有問題,還請包含)
Module
具有獨立功能的模塊
Module中可能還包含有Module
implementation分號之後的部分
Group
Module的集合
implementation分號之前的部分
實例分析
以下圖爲例,加入我們要了解com.android.support:design:26.1.0中,group和module分別是哪些呢?
在Terminal中輸入指令
gradlew -q app:dependencies
在 Maven Repository中查找com.android.support:design:26.1.0
可以清晰的看到,group爲:com.android.support,
module爲下面的內容:
support-v4
appcompat-v7
recyclerview-v7
transition
解決依賴
解決依賴本文提供兩種方式
exclude方式
特點:
配置較爲麻煩,需要在引起衝突的每個依賴上進行exclude操作
配置繁瑣,不美觀
通過configurations方式
特點:
在configurations中,統一指定要配置的方式
配置簡單,較爲整潔
通過configurations.all同一版本
當然還有其他的依賴問題,後續再補充。
屏幕適配
屏幕適配基本和9.0之前版本沒多大差異,除了再增加下劉海屏處理:
// 9.0以上劉海屏適配
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
WindowManager.LayoutParams lp = getWindow().getAttributes();
lp.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
getWindow().setAttributes(lp);
}