基于安卓9如何兼容低版本软件和兼容安卓9如何兼容低版本软件有什么区别吗

版权声明:本文为博主原创文章未经博主允许不得转载。 /aqi00/article/details/

《Android Studio开发实战 从零基础到App上线(第2版)》在书后面的附录中给出了Android8和Android9的主要特性说明附录表格如下图所示:

不过附錄表格只涵盖了常见的功能代码适配,而Android8和Android9的众多新特性还涉及到其它的代码适配下面就补充列出Android8和Android9的额外兼容处理说明:

完整的代码唎子见以下github页面

2、普通应用不允许修改系统设置 也就是Android8.0之后无法再调用系统设置的修改方法Settings.System.putInt,像原来在代码里调整屏幕亮度的办法就不再適用了 完整的代码例子见以下github页面

完整的代码例子见以下github页面

完整的代码例子见以下github页面

2、默认禁止访问http地址,只允许方法https地址如果仍要访问http地址,需要修改配置 Android9开始默认使用加密连接也就是只能访问https打头的网络地址,不能访问http打头的网络地址(如果访问http地址就会报錯“No Network Security Config

配置完毕重新运行network模块就能访问http打头的地址了。 其它无法访问网络图片、无法打开网页、无法下载APK等问题均可照此办理。或者直接把http换成https也行

完整的代码例子见以下github页面

最近遇见了安卓9如何兼容低版本軟件低版本兼容高版本的问题在网上发现了一篇文章讲的超好,特此转载

在Android系统中向下兼容性比较差,但是一个应用APP经过处理还是可鉯在各个版本间运行的向下兼容性不好,不同版本的系统其API版本也不同自然有些接口也不同,新的平台不能使用旧的API旧的平台也使鼡不了新的API。

        为了应用APP有更好的兼容性咱们可以利用高版本的SDK开发应用,并在程序运行时(Runtime)对应用所运行的平台判断旧平台使用旧嘚API,而新平台可使用新的API这样可以较好的提高软件兼容性。

  在Android SDK开发文档中有段话这样的话:


VERSION表示当前系统版本的信息其中僦包括SDK的版本信息,用于成员SDK_INT表示;

其成员就是一些从最早版本开始到当前运行的系统的一些版本号常量

  在我们自己开发应用过程Φ,常常使用如下的代码形式判断运行新API还是旧的API:


 // 包含新API的代码块
 // 包含旧的API的代码块

     OK大家都知道原理了吧! 需要实例的百度蛮多的,这裏就不提供了

不明白题主的“向下兼容”具体指哪方面,就我理解的来说吧:

为了使老版本的sdk能用上新版本的特性和功能官方都会给絀额外的jar包,还是以 fragment 为例如果我开发的app必须要能在 2.3的系统上运行,但同时要使用 fragment 怎么办呢此时就可以用引入android.support.v4.jar包,这就是官方给的兼容性解决方案了

如果你想详细了解下某些版本的升级带来了哪些新特性,欢迎访问当然,感兴趣的话也可以找到历史版本的升级记录茬这里就不多说了。。

Android 版本更替新的版本带来新的特性,新的方法

新的方法带来许多便利,但无法在低版本系统上运行如果兼容性处理不恰当,APP在低版本系统上运行时将会crash。

本文以一个具体的例子说明如何在使用高API level的方法时处理好兼容性问题

例子:根据给出路徑,获取此路径所在分区的总空间大小

获取文件系统用量情况,在API level 9及其以上的系统可直接调用File对象的相关方法,以下需自行计算

为了运行时不报错, 需要:

  1. 判断运行时版本在低版本系统不调用此方法
  2. 同时为了保证功能的完整性,需要提供低版本功能实现

  1. 运行时判断API level; 仅在足够高有此方法的API level系统中,调用此方法;
  2. 保证功能完整性保证低API版本通过其他方法提供功能实現。

鉴于ANDROID SDK 更新较快很多新的特性和API在低版本中的可能没有。所以开发过程中尽量要保持对新功能接口的兼容

一般开发过程中APP都会有一個最低版本的配置,例如如果要兼容到android 2.2系统则可以设置minSdkVersion=8,这就表明能向下兼容到android 2.2版本即APP能在android2.2版本上的手机也能正常运行,即使可能某些新特性的功能支持失效但至少保证不会出现崩溃的问题,而避免此问题的方式就要求开发者在代码中做好兼容和适配

一般选择APP的最低支持版本原则是尽量向下保持兼容,但也不是说越向下越好主要的考虑因素有以下几点:

2.      APP的针对用户群体,比如是高端的用户群体屌丝用户群体,还是中低端用户群体根据不同的用户群体可以综合出来决定对最低版本的支持。

基于SDK高低开发优缺点

基于低版本的SDK开发

優点就是你可以支持的手机用户会更多基本上各个版本的用户都可以用你的应用。

但缺点也是非常明显特别是对开发者来说,需要做恏每一个新特性功能的适配和开发随着版本越来越高,这对开发者后期的维护会越来越困难越来越多。

基于高版本的SDK开发

如果你用最噺的版本的SDK, 优点就是你可以使用最新的功能的api,而且编译也不会出现任何问题

但是缺点就是你需要时刻对你调用的api保持向下兼容性,因为佷有可能你现有调用的某个api在低版本中根本就不存在这时候你需要考虑低版本系统的用户的运行问题了。

如某个工程配置中的最低版本昰android2.2也就是正常来说开发过程中需要基于android SDK为8来做工程开发。但如果你没有基于adroid  2.2 SDK版本开发而是支持了一个更高的版本,比如android 4.0 SDK开发那么很哆高版本的功能特性(2.3—4.0)在4.0以下的手机中运行就可以存在问题,一般的结果就是直接crash

下面是基于android2.2 SDK 开发环境编译的最新的工程,其中就囿一些直接编译运行不过的错误下面可以看几个实例:

代码中使用Bundle对象在新版本中才提供的方法而没有加兼容处理,如下官方文档中解釋该方法在android 3.1后才有。

如果在低于android 3.0下机器运行和编译该代码如果不做任何处理,会直接编译通不过

如果是基于高版本的SDK开发,则新的api肯定会有该方法如果想让编译的版本在低版本中也能运行,则需要考虑到版本兼容的问题可以用如下的方式:

如果是基于低版本SDK开发,那么新版本中的新接口肯定会编译不过这时候可以考虑反射的方式先去查找是否存在这个方法,如果有就代表用户的手机支持该调用方法如果没有则采用低版本的处理方式。

此方法应用场景如2可以将高版本的api接口封装后在高版本的SDK中编译运行jar包,供旧版本的工程中動态加载


在全世界现在人们手里有着各種各样的基于Android的设备。而这些设备中有很多种Android平台的版本在使用,一些运行着最新版平台而另一些还在运行着老的版本。作为一名开發人员你需要考虑你的应用程序是否支持后向兼容——你想你的应用程序能在所有的设备上运行吗,或是只是在最新的平台上运行在某些情况下,在支持的设备上部署新的API并支持老的设备是很有用的。

然而如果你想添加一个有用的但不是必须的特性时,例如在硬件鍵盘可用的时候弹出一个屏幕键盘你可以这样书写你的代码:允许你的程序使用新的特征,而在老的设备上不会失败

最简单的方式是通過反射的方式来调用这个方法这需要做一次查找并在Method对象上进行缓存。调用这个方法实质上是在调用Method.invoke并对结果进行拆箱。参考以下内嫆:





使用静态初始化方法来调用initCompatibility进行方法的查找。如果查找成功的话使用一个私有的方法(与原始的函数签名一致——参数,返回值、异常检查)来替换方法的调用返回值(如果有的话)和异常都如同原始的方法一样进行返回。fiddle方法演示了程序的选择逻辑是调用新嘚API还是在新API无效的情况下作其它的事情。

对于每个你想调用的方法你可能要添加一个额外的私有Method字段,字段初始化方法和对调用的包裝方法。

如果想调用一个之前未定义的类的方法的话就比较复杂了。并且调用Method.invoke()比直接调用这个方法要慢很多。这种情况可以通过一个包装类来缓和一下

想法是创建一个新的类,来包装新的或已经存在的类暴露出来的所有的新API包装类中的每个方法只是调用相应的真实方法并返回相同的结果。

如果目标类和方法存在的话能得到与直接调用相同的行为,并有少量的性能损失如果目标类或方法不存在的話,包装类的初始化会失败并且你的应用程序知道必须避免使用这些新的方法。






我们可能这样创建一个包装类:







包装类拥有和原始类一模一样的方法和构造函数加上一个静态的初始化方法和测试方法来检查新类是否存在。如果新类不可获得的话WrapNewClass的初始化会失败,因此要确保包装类在这种情况下不要被使用。checkAvailable方法是一种强制类进行初始化的简单方法我们可以像这样来使用:



如果调用checkAvailable成功,我们知道噺的类是系统的一部分如果它失败了,我们知道新的类不存在并作相应的调整。应该指出的是由于字节码校验不支持对一个不存在嘚类的引用,因此在调用checkAvailable之前就有可能失败。像实例代码那样构建结果是一样的,可能字节码校验抛出异常或者Class.forName的调用抛出异常

当包装一个有新方法的已存类时,你只需要在包装类中添加新的方法老的方法直接调用。新的方法需要在WrapNewClass的静态初始化方法中作一次反射檢查

你必须测试任何想支持的Android框架版本。一般来说应用程序在不同的版本上行为不同。记住一条法则:如果你不尝试它就不能工作。

你可以在老版本平台的模拟器上运行应用程序来测试程序的后向兼容性由于可以创建不同API等级的“虚拟设备”,因此你可以很容易哋进行测试。一旦你创建了***D你就可以在新老版本系统上进行程序测试,也许你还可以一边测试一边观察它们的不同点


参考资料

 

随机推荐