1. 程式人生 > >Android-0.Android中minsdkversion和targetSdkVersion的選擇

Android-0.Android中minsdkversion和targetSdkVersion的選擇

問題

在呼叫系統播放mp4時,程式碼如下:

 private void viewMediaFile(String path) {
        if (!TextUtils.isEmpty(path)) {
            String type = "video/*";
            if (path.contains("png") || path.contains("jpeg") || path.contains("jpg")) {
                type = "image/*";
            }
            String value = String.valueOf(path);
            File file = new File(value);

            Intent intent = new Intent();
            intent.setAction(android.content.Intent.ACTION_VIEW);
            intent.setDataAndType(Uri.fromFile(file), type);
            startActivity(intent);
        }
    }

發現原工程可以正常呼叫,而我的demo卻直接崩潰了,錯誤如下:

android.os.FileUriExposedException: 
file:///storage/emulated/0/Movies/VID_88.mp4 exposed beyond app through Intent.getData()

最後得出結論為targetSdkVersion不同,我的demo設定成了28,而原工程是21,從而導致行為不同。

簡介

targetSdkVersion即目標軟體開發版本,在建立每一個Android專案的時候都需要選擇targetSdkVersionminSdkVersion,一個targetSdkVersion

的屬性值表示建立的Android專案使用哪個API版本,高版本API程式設計介面可以相容低版本API程式設計介面,反之則不行。 、 Android 7.0定義的手機系統的版本,該系統的版本對外開放的應用程式介面被定義為API 24,如果開發者想要使用Android 7.0系統提供的新功能,這些功能包括:多視窗支援、通知顯示變更、JIT/AOT編譯、快速的應用安裝路徑等,那麼就需要選擇API 24的應用程式介面。

 targetSdkVersion 24

API 19開發的Android專案在Android 7.0系統的手機上執行。 或 API 24開發的Android專案在Android 4.x系統的手機上執行。 它們執行的效果是否一樣呢? API 23開發的應用程式在低於Android 6.0系統上執行時,如果許可權被禁用後,會提示如下圖:

但是,如果API 23開發的應用程式在高於或等於Android 6.0系統的手機上執行時需要自己定義執行時許可權申請的程式碼: https://blog.csdn.net/hgy413/article/details/82968070 如果需要顯示類似於上面圖片顯示的Toast提示,開發者需要在onRequestPermissionResult回撥方法中,列印拍照許可權被禁用,請在許可權管理修改這句話。

舉這個例子的目的,想要說明為什麼在API 23版本開發的APP在低於Android 6.0系統不會執行上述程式碼的原因。 高版本的API定義了一些程式設計介面,但是通常不需要開發者考慮是否高版本API開發的APP在低版本的Android系統的相容性問題,API和Android系統是兩個不一樣的概念,API屬於應用層的東西,Android系統屬於底層的東西,開發者想要顯示底層的演示效果,就需要使用API來完成,如果想要不同的演示效果,又需要考慮選擇哪個版本的API,也就是文章的標題提到的:如何選擇targetSdkVersion屬性值的問題。

如何選擇targetSdkVersion

一個Android系統,對外提供一套API,如何選擇targetSdkVersion取決於應用程式需要實現的功能,如果你的應用程式使用API 10就可以實現的功能,可以不用考慮使用API 24,使用低版本API的其中一個好處,可以讓更多的Android系統執行的效果保持一致,即相容性更好,打個比方:API 10開發的APP可能相容98%以上的Android手機,而API 24開發的APP可能相容僅有60%,所謂的不相容並不是無法正常執行,而是在不同Android系統的手機執行的效果差異比較大,會讓使用者感覺難以接受; 使用低版本API的其中一個不足,顯示的效果比較OUT,提供的可用的介面或類比較少,本來一句程式碼可以完成的功能(封裝的類或介面),需要自己花一天琢磨寫很多的程式碼,也就是有高版本API的其中一個原因,提供更多的或封裝好的應用程式介面讓開發者使用。

同時,高版本API會針對低版本存在的問題進行改進和完善,擯棄一下不用的類或介面,新增一些方法或屬性,如果你使用的方法是在某個API被另一個方法代替的話,你可能就得在程式碼中區分APP是執行在哪個版本的Android系統。一個很典型的例子: WebChromeClientonShowFileChooser()方法和openFileChooser()方法,如果你的targetSdkVersion小於19,在處理WebView上傳表單的資料的時候就需要重寫openFileChooser方法;如果你的targetSdkVersion大於或等於19,你就必須同時重寫onShowFileChooseropenFileChooser兩個方法,openFileChooser方法在Android 4.0以下系統被回撥,另一則在Android 4.0以上系統被回撥。這是高低版本API擯棄或新增一些類和方法時需要注意的其中一個問題。

瞭解並學習Android 4.x、Android 5.x、Android 6.x或Android 7.x系統的特性,重點掌握不同系統同一個功能的實現方式,即行為變更,特點:變更的行為在當前系統或更高系統版本中被支援,一個簡單的例子:Android 7.0系統其中的一個行為變更是許可權更改,嘗試傳遞file:// URI 的方式寫入本地檔案或讀取本地檔案,使用API 24開發的APP將會觸發 FileUriExposedException異常,也即文章開頭提到的問題。

關於minSdkVersion和compileSdkVersion

minSdkVersion定義應用程式支援的最低API版本,最低版本設定為API 11,目標版本設定為API 24,那麼應用程式呼叫使用API 14提供的方法時,Android Studio將提醒開發者引用一個未定義的方法,使用該方法需要將minSdkVersion設定為API 14以上,如下圖:

繼續在上述程式碼,造成的結果大於或等於Android 4.0的系統可以正常執行,小於Android 4.0的系統將在執行時嘗試訪問不可用的API 時發生崩潰。

compileSdkVersion定義應用程式編譯選擇哪個Android SDK版本,通常compileSDKVersion屬性值被設定為最新的API版本,例如:25,改變compileSDKVersion的屬性值不會影響Android系統執行行為,比如說,將屬性值設定為25,targetSdkVersion屬性值為23,程式碼如下:

    compileSdkVersion 25
    buildToolsVersion "25.0.2"
    defaultConfig {
        applicationId "cn.teachcourse.demos"
        minSdkVersion 11
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }

開發的應用程式在Android 7.0系統執行,不會以Android 7.0新增的行為執行,決定Android系統行為的仍然是targetSDKVersion,那麼compileSDKVersion有什麼用呢?

因為環境是compileSdkVersion這個版本的SDK,所以你可以用一些這個版本的API,但是隻是IDE給你的便利性幫助而已,幫助你檢測程式碼,避免使用一些棄用的API。就算你用個低版本的compileSdkVersion,你依然可以那麼寫,但是可能會報錯,報警告,但是你強制打包,其實也是沒有問題的。IDE只是個工具,他的環境也只是工具的環境,不代表你應用執行時的表現。

targetSdkVersion、minSdkVersion和CompileSdkVersion之間的關係

記住一點:Android系統平臺的行為變更,只有targetSdkVersion的屬性值被設定為大於或等於該系統平臺的API版本時,才會生效;compileSdkVersion屬於Android編譯專案時其中的一項配置,主要區別是compileSDKVersion不會被打包的APK檔案中,targetSdkVersionminSdkVersion將被打包到APK檔案中,具體可以解壓APK檔案後,檢視AndroidManifest.xml檔案,如下圖: