Android 9.0 适配指南

国内从去年开始就有消息说,应用上架或者更新要求TargetSdkVersion最低要为26以上,也就是最低也要适配到8.0。今年来也都逐步地开始落实。

还包括从8月份开始在Google Play上发布的应用必须支持64位架构。可以看到适配工作真的不能像以前一样随心所欲了。好在我之前也有写过相关的适配攻略,Android适配系列:

Android 6.0 的动态权限管理
Android 7.0脱坑指南
Android 8.0适配指北

1.Http请求失败

在9.0中默认情况下启用网络传输层安全协议 (TLS),默认情况下已停用明文支持。也就是不允许使用http请求,要求使用https。
比如我使用的是okhttp,会报错:

java.net.UnknownServiceException: CLEARTEXT communication to xxxx not permitted by network security policy

解决方法是需要我们添加网络安全配置。首先在 res 目录下新建xml文件夹,添加network_security_config.xml文件:



    

AndroidManifest.xml中的application添加:



    
          ...
    

以上这是一种简单粗暴的配置方法,要么支持http,要么不支持http。为了安全灵活,我们可以指定支持的http域名:





    secure.example.com
    cdn.example1.com


当然不止这些配置,还有抓包配置、设置自定义CA以及各种场景下灵活的配置,详细的方法可以查看官方文档。

2.Apache HTTP 客户端弃用

在 Android 6.0 时,就已经取消了对 Apache HTTP 客户端的支持。从 Android 9.0 开始,默认情况下该库已从 bootclasspath 中移除。但是耐不住有些SDK中还在使用,比如我见到的友盟QQ分享报错问题。
所以要想继续使用Apache HTTP,需要在应用的 AndroidManifest.xml 文件中添加:


3.前台服务

可以试着搜索一下你的代码,看是否有调用startForegroundService 方法来启动一个前台服务。

Intent intentService = new Intent(this, MyService.class);
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
    startForegroundService(intentService);
} else {
    startService(intentService);
}

9.0 要求创建一个前台服务需要请求 FOREGROUND_SERVICE 权限,否则系统会引发 SecurityException。

java.lang.RuntimeException: Unable to start service com.weilu.test.MyService@81795be with Intent { cmp=com.weilu.test/.MyService }: 
java.lang.SecurityException: Permission Denial: startForeground from pid=28631, uid=10626 requires android.permission.FOREGROUND_SERVICE
    at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3723)
    at android.app.ActivityThread.access$1700(ActivityThread.java:201)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1705)
    at android.os.Handler.dispatchMessage(Handler.java:106)
    at android.os.Looper.loop(Looper.java:207)
    at android.app.ActivityThread.main(ActivityThread.java:6820)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:547)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:876)

解决方法就是AndroidManifest.xml中添加FOREGROUND_SERVICE权限:


4.启动Activity

在9.0 中,不能直接非 Activity 环境中(比如Service,Application)启动 Activity,否则会崩溃报错:

java.lang.RuntimeException: Unable to create service com.weilu.test.MyService: android.util.AndroidRuntimeException: Calling startActivity() from outside of an Activity  context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?
    at android.app.ActivityThread.handleCreateService(ActivityThread.java:3578)
    at android.app.ActivityThread.access$1400(ActivityThread.java:201)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1690)
    at android.os.Handler.dispatchMessage(Handler.java:106)
    at android.os.Looper.loop(Looper.java:207)
    at android.app.ActivityThread.main(ActivityThread.java:6820)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:547)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:876)

这类问题一般会在点击推送消息跳转页面这类场景,解决方法就是 Intent 中添加标志FLAG_ACTIVITY_NEW_TASK,

Intent intent = new Intent(this, TestActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);

你可能感兴趣的:(Android 9.0 适配指南)