Android 9.0遇到的问题和解决方法
1. QQ 分享报错,提示找不到org/apache/http/conn/scheme/SchemeRegistry 类。
Error:
App的targetSdkVersion设置为28时,在Android 9.0的手机上进行QQ分享报错。提示找不到 org/apache/http/conn/scheme/SchemeRegistry 类。
原因:
Apache HTTP 客户端弃用(摘自Android 9.0官方变更说明)
https://developer.android.google.cn/about/versions/pie/android-9.0-changes-28#apache-p
Apache HTTP 客户端弃用
在 Android 6.0 中,我们取消了对 Apache HTTP 客户端的支持。 从 Android 9 开始,默认情况下该内容库已从 bootclasspath 中移除且不可用于应用。
解决:
要继续使用 Apache HTTP 客户端,以 Android 9 及更高版本为目标的应用可以向其 AndroidManifest.xml 添加以下内容:
<uses-library android:name="org.apache.http.legacy" android:required="false"/>
注:拥有最低 SDK 版本 23 或更低版本的应用需要 android:required="false" 属性,因为在 API 级别低于 24 的设备上,org.apache.http.legacy 库不可用。 (在这些设备上,Apache HTTP 类在 bootclasspath 中提供。)
作为使用运行时 Apache 库的替代,应用可以在其 APK 中绑定自己的 org.apache.http 库版本。 如果进行此操作,您必须将该库重新打包(使用一个类似 Jar Jar 的实用程序)以避免运行时中提供的类存在类兼容性问题。
2.非全屏Activity不能设置orientation
Error:
java.lang.IllegalStateException: Only fullscreen activities can request orientation
原因:
这个问题貌似已经被广泛的讨论了,最终我们锁定了April 26的一个commit:
这个改动中抛出异常有关的代码如下:
if (ActivityInfo.isFixedOrientation(requestedOrientation)
&& !fullscreen
&& appInfo.targetSdkVersion >= O) {
throw new IllegalStateException("Only fullscreen activities can request orientation");
}
基本的意思是说,“fullscreen”为否的activity是不能锁定orientation的,否则抛出异常。下面,我们在看一下“fullscreen”如何定义的。
public static boolean isTranslucentOrFloating(TypedArray attributes) {
final boolean isTranslucent = attributes.getBoolean(com.android.internal.R.styleable.Window_windowIsTranslucent, false);
final boolean isSwipeToDismiss = !attributes.hasValue( com.android.internal.R.styleable.Window_windowIsTranslucent)
&& attributes.getBoolean( com.android.internal.R.styleable.Window_windowSwipeToDismiss, false);
final boolean isFloating = attributes.getBoolean(com.android.internal.R.styleable.Window_windowIsFloating, false);
return isFloating || isTranslucent || isSwipeToDismiss;
}
根据上面的定义,如果一个Activity的Style符合下面三个条件之一,认为不是“fullscreen”:
1.“windowIsTranslucent”为true;
2.“windowIsTranslucent”为false,但“windowSwipeToDismiss”为true;
3.“windowIsFloating“为true;
综上可见,这个改动的目的是想阻止非全屏的Activity锁定屏幕旋转,因为当前Activity是透明的,浮动的或可滑动取消的,是否锁屏应该由全屏的Activity决定,而不是并没有全部占据屏幕的Activity决定。
解决:
这个问题貌似在最新的SDK中已经修复,我们在API Level 27的设备上已经无法重现,但我们手头的API Level 26的设备还是能重现。而且根据上面的代码来看,如果想保留当前Activity的style,“isTranslucentOrFloating”的逻辑根本没法绕过,所以想绕开很难,目前能想到的大概两个方向:
1 推迟SDK升级,等官方修复被大多数设备采用;
2 升级SDK,但重构一下代码,看看已有的非“fullscreen” Activity是不是都是必要的,例如用Fragment实现周围半透明效果,能不能直接把Fragment加入到当前Activity(当然Detach Fragment是有重绘View的开销的)。
3. http请求报错
Error:
在Android P 使用HttpUrlConnection进行http请求会出现以下异常:
java.io.IOException: Cleartext HTTP traffic to **** not permitted
使用OKHttp请求则出现:
java.net.UnknownServiceException: CLEARTEXT communication ** not permitted by network security policy
原因:
Google表示,为保证用户数据和设备的安全,针对下一代 Android 系统(Android P) 的应用程序,将要求默认使用加密连接,这意味着 Android P 将禁止 App 使用所有未加密的连接,因此运行 Android P 系统的安卓设备无论是接收或者发送流量,未来都不能明码传输,需要使用下一代(Transport Layer Security)传输层安全协议,而 Android Nougat 和 Oreo 则不受影响。
在Android P系统的设备上,如果应用使用的是非加密的明文流量的http网络请求,则会导致该应用无法进行网络请求,https则不会受影响,同样地,如果应用嵌套了webview,webview也只能使用https请求。
解决:
有人认为 Android P 上所有的 App 都需要使用 TLS 加密会降低上网体验,事实上这是一种误解,至于 App 对于少数旧服务器的连接如果非要使用明码传输,开发者需要更改 App 的网络安全配置以允许此类连接。
有以下三种解决方案
-
APP改用https请求
-
targetSdkVersion 降到27以下
-
在 res 下新增一个 xml 目录,然后创建一个名为:network_security_config.xml 文件(名字自定) ,内容如下,大概意思就是允许开启http请求
<?xml version="1.0" encoding="utf-8"?> <network-security-config> <base-config cleartextTrafficPermitted="true" /> </network-security-config>
当然也可以针对特定的域名自定义配置
参考:https://developer.android.com/training/articles/security-config.html然后在APP的AndroidManifest.xml文件下的application标签增加以下属性
<application ... android:networkSecurityConfig="@xml/network_security_config" ... />
网友评论