个别旧项目仍然还是用eclipse开发,所以sdk也用的低,这不又出问题了。Android P上,应用打开会弹出对话框,内容:“此应用专为旧版Android打造,因此可能无法正常运行。请尝试检查更新或与开发者联系”。

                                                 

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

应用启动,startActivity时,流程会执行到realStartActivityLocked方法,代码位于ActivityStackSupervisor.java,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打造,因此可能无法正常运行。请尝试检查更新或与开发者联系”。

查看eclipse项目,没有targetSdk,但是有minSdkVersion

把minSdkVersion改为16问题还是一样在,改为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。如果是eclipse项目没有targetSdk,那就把minSdkVersion改为17.

更多相关文章

  1. 你真的懂Android(安卓)Handler吗?(一)
  2. 读写Android中assets目录下的文件的方法详解
  3. Android(安卓)动态权限最全解析
  4. Android(安卓)Activity 完全解析(上)
  5. android 搜索
  6. 事件处理机制之Gestures(手势)
  7. Android(安卓)—— 注解(Annotation)也被称为元数据(Metadata)
  8. Android基础笔记(十一)- Service基础和注意事项以及Activity与Serv
  9. Android异步处理机制AsyncTask的理解

随机推荐

  1. 短小精悍,双指针对撞,求解「两数之和 II」
  2. 从零到一学懂区块链(6):哈希函数
  3. (再进阶版)有了四步解题法模板,再也不害怕动
  4. JavaScript 数据结构(2-2):栈与队列-队列篇
  5. 学了那么多公式,却依旧用不好Excel(实例讲
  6. 「图解」缺失的第一个正数
  7. 经验分享:谈谈“面试”
  8. Excel预测工作表
  9. 谷歌浏览器团队:感谢 Flash 所做的一切
  10. 动态规划之空间优化与总结回顾