Android 升级targetSdkVersion 28

在升级Android targetSdkVersion 28的过程中,遇到了几个出现在Android 9.0的机器上的兼容性问题:

Apache HTTP 客户端弃用问题

Google Admob框架在9.0机器上报错:

Caused by java.lang.ClassNotFoundException
Didn't find class "org.apache.http.ProtocolVersion" 
dalvik.system.BaseDexClassLoader.findClass (BaseDexClassLoader.java:134)
java.lang.ClassLoader.loadClass (ClassLoader.java:379)
ad.loadClass (ad.java:4)
java.lang.ClassLoader.loadClass (ClassLoader.java:312)
ly.b (ly.java:2)
lx.a (lx.java:1)
lz.a (lz.java:29)
com.google.android.gms.ads.internal.util.aq.a (aq.java:10)
lc.a (lc.java:8)
lc.run (lc.java:2)

这个是由于Apache HTTP 客户端弃用导致的问题,根据官方文档
),在AndroidManifest中加入以下配置即可:

 
    
    ...

HTTP无法访问

根据官方文档, Android 9.0以上机器已经默认禁止HTTP明文通讯,所以在Android 9.0以上的机器targetSdkVersion>=28时会出现HTTP无法访问的问题,会抛出UnknownServiceException

Cannot send data to the server
    java.net.UnknownServiceException: CLEARTEXT communication to xxx not permitted by network security policy
        at 
...
        at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:254)
        at okhttp3.RealCall$AsyncCall.execute(RealCall.java:200)
        at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
        at java.lang.Thread.run(Thread.java:914)
解决方案
  1. 尽早切换至HTTPS,数据传输更加安全,同时HTTPS也是大势所趋,保不准以后会强制使用

  2. AndroidManifest.xml中配置 android:usesCleartextTraffic="true"


这种方式相当于全局开启HTTP,允许访问所有的HTTP网址

  1. HTTP白名单配置
    res/xml中添加network_security_config.xml配置文件

    
        
        
            secure.example.com
        
    

然后在AndroidManifest.xml中指定该配置文件


Invalid Region.Op 问题

调用canvas.clipRect(newRect, Region.Op.REPLACE)方法时报错java.lang.IllegalArgumentException: Invalid Region.Op - only INTERSECT and DIFFERENCE
根据官方文档,该方法在API 26就已经废弃掉了,更可怕的是在API 28开始只支持Region.Op.INTERSECT 和 Region.Op.DIFFERENCE,说实话这种破坏性的API变更真有点操蛋,说好的向下兼容呢!

image.png

解决方案

只能通过判断API版本的方式来避免或者按照文档使用推荐的clipRect(android.graphics.Rect) or clipOutRect(android.graphics.Rect)来实现了

public class CanvasUtils{
    public void safeClipRect(Canvas canvas, Rect rect, Region.Op op){
       if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.P){
         canvas.clipRect(rect);
       }else {
         canvas.clipRect(rect, op);
      }
  }
}

你可能感兴趣的:(Android 升级targetSdkVersion 28)