Android9.0网络兼容和依赖适配问题


        客观来说,9.0兼容好像问题不是很大,很多的APP一点问题都没有,但是有些比较旧的APP就问题比较多了,下面简单写一下解决方法,本文纯属笔记,方便以后查看。

网络问题:

问题一

应对9.0 版本的网络明暗流量问题

设置一下 application (清单文件里面)

 

问题二

引用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下的节点加入以下相关依赖(如果项目继续使用Apache的httpclient),这是因为httpclient在Android6.0就已经被废弃了,如果不想大变动我们可以将这个库强制依赖进来,避免报错。

       

同时在app目录下build.gradle的android节点加入httpclient依赖:

 useLibrary 'org.apache.http.legacy'

Android9.0官方要求中,禁止传输接收没加密的数据,也就是说对网络数据传输这一块做了限制,我们需要在AndroidManifest.xml中的节点内加入网络安全配置:

 

 其中network_security_config.xml在xml目录如下:



    

 

依赖问题

我们升级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);
        }