Android 开发之API兼容问题

问题背景

鉴于ANDROID SDK 更新较快,不少新的特性和API在低版本中的可能没有。因此开发过程当中尽可能要保持对新功能接口的兼容。html

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

 

兼容原则

通常选择APP的最低支持版本原则是尽可能向下保持兼容,但也不是说越向下越好,主要的考虑因素有如下几点:android

1.      各个低版本手机的市场占有率,好比2013年android 2.2的手机还占用必定的市场份额,但到如今为止基本上该份额能够忽略不计了(目前android 最高的版本已达到android 5.1了)api

2.      APP的针对用户群体,好比是高端的用户群体,屌丝用户群体,仍是中低端用户群体,根据不一样的用户群体能够综合出来决定对最低版本的支持。ide

基于SDK高低开发优缺点

基于低版本的SDK开发ui

优势就是你能够支持的手机用户会更多,基本上各个版本的用户均可以用你的应用。spa

但缺点也是很是明显,特别是对开发者来讲,须要作好每个新特性功能的适配和开发,随着版本愈来愈高,这对开发者后期的维护会愈来愈困难,愈来愈多。.net

基于高版本的SDK开发orm

若是你用最新的版本的SDK, 优势就是你可使用最新的功能的api,并且编译也不会出现任何问题。htm

可是缺点就是你须要时刻对你调用的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 开发环境编译的最新的工程,其中就有一些直接编译运行不过的错误。下面能够看几个实例:

SampleActivity.java有一处这样写的:

      if (savedInstanceState !=null) {

         mOrderId =savedInstanceState.getString(EXTRA_ORDER_ID);

         mPaySuccess =savedInstanceState.getString(EXTRA_PAY_SUCCESS,"");

      }

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

public String getString (String key, String defaultValue) Added in API level 12

若是在低于android 3.0下机器运行和编译该代码,若是不作任何处理,会直接编译通不过。

 

解决方法:

1.       用android提供的注解 @TargetApi(11)+ 版本号控制作兼容

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

/***

     * 该api版本兼容获取指定参数

     *

     * @param savedInstanceState

     * @return

     */

   @TargetApi(12)

   privateString getPaySucess(Bundle savedInstanceState) {

        if (Build.VERSION.SDK_INT >= 12) {

            mPaySuccess = savedInstanceState.getString(EXTRA_PAY_SUCCESS,"");

        } else {

            mPaySuccess = savedInstanceState.getString(EXTRA_PAY_SUCCESS);

            if (mPaySuccess ==null){

                mPaySuccess = "";

            }

        }

        returnmPaySuccess;

}

 

2.       用反射的方式调用高版本中的新功能接口进行调用。

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

 

   /***

     * 经过放射的方式来获取Bundle中的

     * getString(String key,String value)方法

     *

     * @return

     */

   privateStringgetPaySucessInvoke(Bundle savedInstanceState) {

 

        try {

            Class<?> c = Class.forName("android.os.bundle");

            Method mGetString2Params =c.getDeclaredMethod("getString", String.class,String.class);

 

            if (mGetString2Params !=null) {

                mPaySuccess = (String)mGetString2Params.invoke(null,EXTRA_PAY_SUCCESS,"");

            } else {

                mPaySuccess = savedInstanceState.getString(EXTRA_PAY_SUCCESS);

                if (mPaySuccess ==null){

                    mPaySuccess ="";

                }

            }

        } catch (Exception e) {

            // TODO: handle exception

        }

 

        returnmPaySuccess;

    }

 

3.       分离代码,分别在不一样的SDK上编译运行,最后ClassLoader动态加载高版本中的相关类接口

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

SDK相关对应表

Platform Version

API Level

VERSION_CODE

Notes

Android 5.1

22

LOLLIPOP_MR1

Platform Highlights

Android 5.0

21

LOLLIPOP

Android 4.4W

20

KITKAT_WATCH

KitKat for Wearables Only

Android 4.4

19

KITKAT

Platform Highlights

Android 4.3

18

JELLY_BEAN_MR2

Platform Highlights

Android 4.2, 4.2.2

17

JELLY_BEAN_MR1

Platform Highlights

Android 4.1, 4.1.1

16

JELLY_BEAN

Platform Highlights

Android 4.0.3, 4.0.4

15

ICE_CREAM_SANDWICH_MR1

Platform Highlights

Android 4.0, 4.0.1, 4.0.2

14

ICE_CREAM_SANDWICH

Android 3.2

13

HONEYCOMB_MR2

Android 3.1.x

12

HONEYCOMB_MR1

Platform Highlights

Android 3.0.x

11

HONEYCOMB

Platform Highlights

Android 2.3.4
Android 2.3.3

10

GINGERBREAD_MR1

Platform Highlights

Android 2.3.2
Android 2.3.1
Android 2.3

9

GINGERBREAD

Android 2.2.x

8

FROYO

Platform Highlights

Android 2.1.x

7

ECLAIR_MR1

Platform Highlights

Android 2.0.1

6

ECLAIR_0_1

Android 2.0

5

ECLAIR

Android 1.6

4

DONUT

Platform Highlights

Android 1.5

3

CUPCAKE

Platform Highlights

Android 1.1

2

BASE_1_1

Android 1.0

1

BASE

相关文章
相关标签/搜索