此版本专为旧版android打造,应用弹窗“此应用专为旧版Android打造,因此可能无法正常运行...”的原因...

Android P上,有的应用打开时,会弹出对话框,内容:“此应用专为旧版Android打造,因此可能无法正常运行。请尝试检查更新或与开发者联系”。用户会感到困惑,真正的原因是什么?

举例,如下图某应用,版本:6.072.001,

9dc825ac1c58?from=groupmessage

下面通过Android P源码,分析原因:

应用启动,startActivity时,流程会执行到realStartActivityLocked方法,代码位于ActivityStackSupervisor.java,可参考我之前一篇文章:startActivity启动流程的源码学习。

realStartActivityLocked方法中,会调用AppWarnings.java的onStartActivity方法,如下:

final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app, boolean andResume, boolean checkConfig) throws RemoteException {

try {

// ...

mService.getAppWarningsLocked().onStartActivity(r);

// ...

} catch (RemoteException e) {

// ...

}

}

onStartActivity方法实现:

/**

* Called when an activity is being started.

*

* @param r record for the activity being started

*/

public void onStartActivity(ActivityRecord r) {

showUnsupportedCompileSdkDialogIfNeeded(r);

showUnsupportedDisplaySizeDialogIfNeeded(r);

showDeprecatedTargetDialogIfNeeded(r);

}

其中第三个函数showDeprecatedTargetDialogIfNeeded重点分析:

/**

* Shows the "deprecated target sdk" warning, if necessary.

*

* @param r activity record for which the warning may be displayed

*/

public void showDeprecatedTargetDialogIfNeeded(ActivityRecord r) {

if (r.appInfo.targetSdkVersion < Build.VERSION.MIN_SUPPORTED_TARGET_SDK_INT) {

mUiHandler.showDeprecatedTargetDialog(r);

}

}

重点:这里出现一个判断方法,正是其决定是否弹窗,判断条件中Build.VERSION.MIN_SUPPORTED_TARGET_SDK_INT,如下:

public static final int MIN_SUPPORTED_TARGET_SDK_INT = SystemProperties.getInt(

"ro.build.version.min_supported_target_sdk", 0);

此属性默认值,一般是17。也就是说:

Android P机型上,当应用的targetSdk版本低于17时,应用启动时会弹窗“此应用专为旧版Android打造,因此可能无法正常运行。请尝试检查更新或与开发者联系”。

那么查看截图的某应用Package信息:

Package [com.qqgame.hlddz] (5ecd50f):

......

versionCode=196 minSdk=8 targetSdk=8

versionName=6.043.001

果然其App的targetSdk是8,远低于17。

解决了核心问题,继续跟进showDeprecatedTargetDialog方法的实现,会发现其主要是调用对话框类DeprecatedTargetSdkVersionDialog,来弹出此对话框,并显示提示。

这里有一个问题,既然是在每个Activity启动时会调用AppWarnings.java的onStartActivity方法,那会不会每次打开新Activity,都弹此对话框?如果这样,用户体验也会非常不好。

答案:不会的,这里有一个小技巧,第一次弹出对话框后,用户如果选择“确定”,AMS会给此应用设置一个Flag标识:FLAG_HIDE_DEPRECATED_SDK。每次准备弹窗时,会先判断此标识值是否为true,如果是,说明已经提示过用户,无需再弹窗。代码如下:

public DeprecatedTargetSdkVersionDialog(final AppWarnings manager, Context context, ApplicationInfo appInfo) {

// ...

final AlertDialog.Builder builder = new AlertDialog.Builder(context)

.setPositiveButton(R.string.ok, (dialog, which) ->

manager.setPackageFlag(

mPackageName, AppWarnings.FLAG_HIDE_DEPRECATED_SDK, true))

.setMessage(message)

.setTitle(label);

// ...

}

最后,结论如下:

Android P机型上,当应用的targetSdk版本低于17时,应用启动时会弹窗“此应用专为旧版Android打造,因此可能无法正常运行。请尝试检查更新或与开发者联系”。标准值由ro.build.version.min_supported_target_sdk值设定的,一般默认是17

作者:kevin song,2019.1.23于南京建邺区

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值