build.gradle里的targetSdkVersion
从 26增加到 29;下面是我们遇到一些兼容性问题
http网络请求崩溃
java.io.IOException: Cleartext HTTP traffic to 包名 not permitted
原因分析:
android 9.0默认使用https网络请求,http请求需要手动打开
解决办法:
AnroidManifest.xml中的application显示设置
<application android:usesCleartextTraffic="true">
android 8.0透明Activity设置方向崩溃
Only fullscreen opaque activities can request orientation
原因分析:
我们项目大部分都是锁垂直方向。然而8.0的系统在透明主题时,如果请求方向,直接抛出崩溃
解决办法:
8.0透明activity不锁死方向,系统沿用上个页面的方向
比较优雅的解决办法,不改业务代码https://blog.csdn.net/starry_eve/article/details/82777160
这个要特别注意第三方,比如友盟分享的中转页,也是锁死方向导致崩溃的,要一一排查
- 前台线程权限崩溃
9.0需要在manifest里声明前台线程权限,才能使用
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
前台线程注意区分版本
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
context.startForegroundService(starter);
} else {
context.startService(starter);
}
4.多进程访问WebView,崩溃问题
Caused by: java.lang.RuntimeException: Using WebView from more than one process at once with the same data directory is not supported. https://crbug.com/558377
原因分析:
极光、融云在app主进程外,创建了各自的通信、保活进程,不在同一个进程里访问webView的时候,在android 9.0以上会报错
解决办法:
Application的onCreate方法里,加入如下判断
//融云和app都会初始化application一次,这里避免了融云初始化的步骤
if (!DeviceUtil.isDefaultProcess(this)) {
WebViewUtils.safeWebViewInOtherThread(this);
return; }
public static void safeWebViewInOtherThread(Context context) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
WebView.setDataDirectorySuffix(DeviceUtil.getCurProcessName(context)); }
}
/**
* 判断当前线程名称是否和包名一致
*
* @param context 上下文
* @return true 一致
*/
public static boolean isDefaultProcess(Context context) {
String processName = getCurProcessName(context);
if (TextUtils.isEmpty(processName))
return false;
return processName.equals(context.getPackageName());
}
/**
* 获得当前进程名字
*
* @return 当前进程名称
*/
public static String getCurProcessName(Context context) {
int pid = android.os.Process.myPid();
ActivityManager mActivityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
if (mActivityManager.getRunningAppProcesses() == null)
return "";
Iterator iterator = mActivityManager.getRunningAppProcesses().iterator();
ActivityManager.RunningAppProcessInfo appProcess;
do {
if (!iterator.hasNext()) {
return null;
}
appProcess = (ActivityManager.RunningAppProcessInfo) iterator.next();
} while (appProcess.pid != pid);
return appProcess.processName;
}
https://blog.csdn.net/JiaoJunfeng/article/details/90478935
以下是未遇到,但是会涉及到的问题,要排查
1.黑名单api问题
使用google工具veridex扫描,不要对黑名单里的属性进行反射调用。
深灰名单里,发现国产第三方工具、极光、tinker都有用到,目前暂无影响
项目里扫描后没有黑名单反射
2.加密方式崩溃问题
The Crypto provider has been deleted in Android P (and was deprecated in Android N), so the code will crash.
项目里面的加密算法,如果第二个入参指定了crypto provider就要仔细筛查下https://www.jianshu.com/p/ca8c2f4b0ee6
- 友盟QQ分享失败的问题
如果9.0的手机,在target api 28上面,分享qq会失败。
主要是废弃的apache http库,在9.0里被去掉了,https://developer.umeng.com/docs/66632/detail/94386
但是现在(2019.5.18)友盟分享qq,在几台9.0的手机上均测试通过。
适配10.0
具体怎么适配有文章讲的很清楚https://juejin.cn/post/6844904073024503822#heading-1
下面咱说下自己的适配步骤
1、排查文件有没有放安全区域:内置应用目录、外置(应用目录)
2、文件访问方式,谷歌给出的方案要么适配,要么用兼容方案android:requestLegacyExternalStorage="true"
这样能用老的File方式直接访问特定地方文件
我们选择用android:requestLegacyExternalStorage="true"适配
(在安卓11上,谷歌又默认支持了这种方式,因此只要文件存储在内置、外置(应用目录)位置,都能用以前File的方式直接访问)