日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

Android应用在不同版本间兼容性处理

發(fā)布時間:2025/7/14 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android应用在不同版本间兼容性处理 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

在Android系統(tǒng)中向下兼容性比較差,但是一個應(yīng)用APP經(jīng)過處理還是可以在各個版本間運(yùn)行的。向下兼容性不好,不同版本的系統(tǒng)其API版本也不同,自然有些接口也不同,新的平臺不能使用舊的API,舊的平臺也使用不了新的API。

??????? 為了應(yīng)用APP有更好的兼容性,咱們可以利用高版本的SDK開發(fā)應(yīng)用,并在程序運(yùn)行時(Runtime)對應(yīng)用所運(yùn)行的平臺判斷,舊平臺使用舊的API,而新平臺可使用新的API,這樣可以較好的提高軟件兼容性。

?

??????? 那么,如何在軟件運(yùn)行時做出這樣的判斷呢?答案下邊揭曉:

?

  在Android SDK開發(fā)文檔中有段話這樣的話:

Check System Version at Runtime(在軟件運(yùn)行時檢查判斷系統(tǒng)版本)


Android provides a unique code for each platform version in the?Build?constants class. Use these codes within your app to build conditions that ensure the code thatdepends on higher API levels is executed only when those APIs are available on the system.

private void setUpActionBar() { // Make sure we're running on Honeycomb or higher to use ActionBar APIs if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { ? ActionBar actionBar = getActionBar(); actionBar.setDisplayHomeAsUpEnabled(true); } }

Note:?When parsing XML resources, Android ignores XML attributes that aren’t supported by the current device. So you can safely use XML attributes thatare only supported by newer versions without worrying about older versions breaking when theyencounter that code. For example, if you set the?targetSdkVersion="11", your app includes the?ActionBar?by defaulton Android 3.0 and higher. To then add menu items to the action bar, you need to set?android:showAsAction="ifRoom"?in your menu resource XML. It's safe to do this in a cross-version XML file, because the older versions of Android simply ignore the?showAsAction?attribute (that is, you?do not?need a separate version in?res/menu-v11/).

?

???????????從上面可以知道Android為我們提供了一個常量類Build,其中最主要是Build中的兩個內(nèi)部類VERSION和VERSION_CODES,

VERSION表示當(dāng)前系統(tǒng)版本的信息,其中就包括SDK的版本信息,用于成員SDK_INT表示;

對于VERSION_CODES在SDK開發(fā)文檔中時這樣描述的,Enumeration of the currently known SDK version codes. These are the values that can be found in?SDK. Version numbers increment monotonically with each official platform release.

其成員就是一些從最早版本開始到當(dāng)前運(yùn)行的系統(tǒng)的一些版本號常量。

  在我們自己開發(fā)應(yīng)用過程中,常常使用如下的代碼形式判斷運(yùn)行新API還是舊的API:

?

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { // 包含新API的代碼塊 } else { // 包含舊的API的代碼塊 }

???? OK,大家都知道原理了吧! 需要實(shí)例的百度蠻多的,這里就不提供了。

?

?

?

android 10(2.2.3/2.2.4)及以下的版本是沒有fragment的,從 11(3.0.x) 就有了,這就是新特性,諸如此類的還有很多呢。

不明白題主的“向下兼容”具體指哪方面,就我理解的來說吧:

為了使老版本的sdk能用上新版本的特性和功能,官方都會給出額外的jar包,還是以 fragment 為例,如果我開發(fā)的app必須要能在 2.3的系統(tǒng)上運(yùn)行,但同時要使用 fragment 怎么辦呢?此時就可以用引入android.support.v4.jar包,這就是官方給的兼容性解決方案了。

可以發(fā)現(xiàn),隨著 SDK 版本的不斷升級,官方給出的jar包也越來越多,android.support.v7.jar,v13......

如果你想詳細(xì)了解下某些版本的升級帶來了哪些新特性,歡迎訪問Android 5.0 Behavior Changes,當(dāng)然,感興趣的話也可以找到歷史版本的升級記錄,在這里就不多說了。。。

?

?

?

Android 版本更替,新的版本帶來新的特性,新的方法。

新的方法帶來許多便利,但無法在低版本系統(tǒng)上運(yùn)行,如果兼容性處理不恰當(dāng),APP在低版本系統(tǒng)上,運(yùn)行時將會crash。

本文以一個具體的例子說明如何在使用高API level的方法時處理好兼容性問題。

例子:根據(jù)給出路徑,獲取此路徑所在分區(qū)的總空間大小。

在安卓中的文件存儲使用參考中提到:

獲取文件系統(tǒng)用量情況,在API level 9及其以上的系統(tǒng),可直接調(diào)用File對象的相關(guān)方法,以下需自行計算

一般實(shí)現(xiàn)

就此需求而言,API level 9及其以上,調(diào)用?File.getTotalSpace()?即可, 但是在API level 8 以下系統(tǒng)File對象并不存在此方法。

如以下方法:

/*** Returns the total size in bytes of the partition containing this path.* Returns 0 if this path does not exist.* * @param path* @return -1 means path is null, 0 means path is not exist.*/ public static long getTotalSpace(File path) {if (path == null) {return -1;}return path.getTotalSpace(); }
處理無法編譯通過

如果minSdkVersion設(shè)置為8,那么build時候會報以下錯誤:

Call requires API level 9 (current min is 8)

為了編譯可以通過,可以添加?@SuppressLint("NewApi")?或者?@TargeApi(9)。

用@TargeApi($API_LEVEL)顯式表明方法的API level要求,而不是@SuppressLint("NewApi");

但是這樣只是能編譯通過,到了API level8的系統(tǒng)運(yùn)行,將會引發(fā)?java.lang.NoSuchMethodError。

正確的做法

為了運(yùn)行時不報錯, 需要:

  • 判斷運(yùn)行時版本,在低版本系統(tǒng)不調(diào)用此方法
  • 同時為了保證功能的完整性,需要提供低版本功能實(shí)現(xiàn)

    如下:

    /*** Returns the total size in bytes of the partition containing this path.* Returns 0 if this path does not exist.* * @param path* @return -1 means path is null, 0 means path is not exist.*/ @TargetApi(Build.VERSION_CODES.GINGERBREAD) // using @TargeApi instead of @SuppressLint("NewApi") @SuppressWarnings("deprecation") public static long getTotalSpace(File path) {if (path == null) {return -1;}if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {return path.getTotalSpace();}// implements getTotalSpace() in API lower than GINGERBREADelse {if (!path.exists()) {return 0;} else {final StatFs stats = new StatFs(path.getPath());// Using deprecated method in low API level system, // add @SuppressWarnings("description") to suppress the warningreturn (long) stats.getBlockSize() * (long) stats.getBlockCount();}} }
  • 總結(jié)

    在使用高于minSdkVersion?API level的方法需要:

  • 用@TargeApi($API_LEVEL)?使可以編譯通過, 不建議使用@SuppressLint("NewApi");
  • 運(yùn)行時判斷API level; 僅在足夠高,有此方法的API level系統(tǒng)中,調(diào)用此方法;
  • 保證功能完整性,保證低API版本通過其他方法提供功能實(shí)現(xiàn)。
  • ?

    ?

    ?

    Android 開發(fā)之API兼容問題

    問題背景

    鑒于ANDROID SDK 更新較快,很多新的特性和API在低版本中的可能沒有。所以開發(fā)過程中盡量要保持對新功能接口的兼容。

    一般開發(fā)過程中APP都會有一個最低版本的配置,例如如果要兼容到android 2.2系統(tǒng),則可以設(shè)置minSdkVersion=8,這就表明能向下兼容到android 2.2版本,即APP能在android2.2版本上的手機(jī)也能正常運(yùn)行,即使可能某些新特性的功能支持失效,但至少保證不會出現(xiàn)崩潰的問題,而避免此問題的方式就要求開發(fā)者在代碼中做好兼容和適配。

    ?

    兼容原則

    一般選擇APP的最低支持版本原則是盡量向下保持兼容,但也不是說越向下越好,主要的考慮因素有以下幾點(diǎn):

    1.??????各個低版本手機(jī)的市場占有率,比如2013年android 2.2的手機(jī)還占用一定的市場份額,但到現(xiàn)在為止基本上該份額可以忽略不計了(目前android 最高的版本已達(dá)到android 5.1了)

    2.??????APP的針對用戶群體,比如是高端的用戶群體,屌絲用戶群體,還是中低端用戶群體,根據(jù)不同的用戶群體可以綜合出來決定對最低版本的支持。

    基于SDK高低開發(fā)優(yōu)缺點(diǎn)

    基于低版本的SDK開發(fā)

    優(yōu)點(diǎn)就是你可以支持的手機(jī)用戶會更多,基本上各個版本的用戶都可以用你的應(yīng)用。

    但缺點(diǎn)也是非常明顯,特別是對開發(fā)者來說,需要做好每一個新特性功能的適配和開發(fā),隨著版本越來越高,這對開發(fā)者后期的維護(hù)會越來越困難,越來越多。

    基于高版本的SDK開發(fā)

    如果你用最新的版本的SDK, 優(yōu)點(diǎn)就是你可以使用最新的功能的api,而且編譯也不會出現(xiàn)任何問題。

    但是缺點(diǎn)就是你需要時刻對你調(diào)用的api保持向下兼容性,因?yàn)楹苡锌赡苣悻F(xiàn)有調(diào)用的某個api在低版本中根本就不存在。這時候你需要考慮低版本系統(tǒng)的用戶的運(yùn)行問題了。

    ?

    ?

    實(shí)戰(zhàn)分析

    如某個工程配置中的最低版本是android2.2,也就是正常來說開發(fā)過程中需要基于android SDK為8來做工程開發(fā)。但如果你沒有基于adroid? 2.2 SDK版本開發(fā),而是支持了一個更高的版本,比如android 4.0 SDK開發(fā),那么很多高版本的功能特性(2.3—4.0)在4.0以下的手機(jī)中運(yùn)行就可以存在問題,一般的結(jié)果就是直接crash。

    下面是基于android2.2 SDK 開發(fā)環(huán)境編譯的最新的工程,其中就有一些直接編譯運(yùn)行不過的錯誤。下面可以看幾個實(shí)例:

    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下機(jī)器運(yùn)行和編譯該代碼,如果不做任何處理,會直接編譯通不過。

    ?

    解決方法:

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

    如果是基于高版本的SDK開發(fā),則新的api肯定會有該方法,如果想讓編譯的版本在低版本中也能運(yùn)行,則需要考慮到版本兼容的問題,可以用如下的方式:

    /***

    ???? *?該api版本兼容獲取指定參數(shù)

    ???? *

    ???? *?@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.?????? 用反射的方式調(diào)用高版本中的新功能接口進(jìn)行調(diào)用。

    如果是基于低版本SDK開發(fā),那么新版本中的新接口肯定會編譯不過,這時候可以考慮反射的方式先去查找是否存在這個方法,如果有就代表用戶的手機(jī)支持該調(diào)用方法,如果沒有則采用低版本的處理方式。

    ?

    ???/***

    ???? *?通過放射的方式來獲取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上編譯運(yùn)行,最后ClassLoader動態(tài)加載高版本中的相關(guān)類接口

    此方法應(yīng)用場景如2,可以將高版本的api接口封裝后在高版本的SDK中編譯運(yùn)行jar包,供舊版本的工程中動態(tài)加載。

    SDK相關(guān)對應(yīng)表

    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

    ?

    ?

    參考:

    http://developer.android.com/reference/packages.html

    轉(zhuǎn)載于:https://www.cnblogs.com/yaowen/p/5013366.html

    總結(jié)

    以上是生活随笔為你收集整理的Android应用在不同版本间兼容性处理的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。