【问题标题】:How to fix Expected Android API level 21+ but was 19 in Android如何修复预期的 Android API 级别 21+ 但在 Android 中为 19
【发布时间】:2019-11-11 02:32:54
【问题描述】:

在我的应用程序中,我想从服务器获取数据,为了连接到服务器,我使用了 RetrofitOkHttp
但是在运行应用程序时,显示强制关闭错误。
在 android api 21+ 中没有错误,但在 api 21 下面显示强制关闭错误。

ApiClient 类代码:

class ApiClient constructor(private val deviceUUID: String) {

    private val apiServices: ApiServices

    init {
        //Gson
        val gson = GsonBuilder()
            .setLenient()
            .create()

        //Http log
        val loggingInterceptor = HttpLoggingInterceptor()
        loggingInterceptor.level =
            if (BuildConfig.DEBUG) HttpLoggingInterceptor.Level.BODY else HttpLoggingInterceptor.Level.NONE

        //Http Builder
        val clientBuilder = OkHttpClient.Builder()
        clientBuilder.interceptors().add(loggingInterceptor)
        clientBuilder.addInterceptor { chain ->
            val request = chain.request()
            request.newBuilder().addHeader(AGENT_NAME, AGENT_VALUE).build()
            chain.proceed(request)
        }
        clientBuilder.addInterceptor { chain ->
            val request = chain.request()
            request.newBuilder().addHeader(X_CLIENT_VERSION, APP_VERSION_NAME).build()
            chain.proceed(request)
        }
        clientBuilder.addInterceptor { chain ->
            val request = chain.request()
            request.newBuilder().addHeader(UUID_NAME, deviceUUID).build()
            chain.proceed(request)
        }

        //Http client
        val client = clientBuilder
            .readTimeout(NETWORK_CONNECTIONS_TIME, TimeUnit.SECONDS)
            .writeTimeout(NETWORK_CONNECTIONS_TIME, TimeUnit.SECONDS)
            .connectTimeout(NETWORK_CONNECTIONS_TIME, TimeUnit.SECONDS)
            .retryOnConnectionFailure(true)
            .build()

        //Retrofit
        val retrofit = Retrofit.Builder()
            .baseUrl(BASE_URL)
            .client(client)
            .addConverterFactory(GsonConverterFactory.create(gson))
            .addCallAdapterFactory(RxJava2CallAdapterFactory.createWithScheduler(Schedulers.io()))
            .build()

        //Init apiServices
        apiServices = retrofit.create(ApiServices::class.java)
    }

    companion object {
        private var apiClient: ApiClient? = null

        fun getInstance(deviceUUID: String): ApiClient =
            apiClient ?: synchronized(this) {
                apiClient ?: ApiClient(deviceUUID).also {
                    apiClient = it
                }
            }
    }

    /**
     * Send apiServices to ApisUseCase for initialize all of apis
     */
    fun apisUseCase(): ApisUseCase {
        return ApisUseCase(apiServices)
    }
}

显示此行的错误:.build() 在此方法上 val client = clientBuilder

我将此代码添加到 gradle.build

compileOptions {
    sourceCompatibility = '1.8'
    targetCompatibility = '1.8'
}

但再次显示错误!

错误信息:

java.lang.ExceptionInInitializerError
    at okhttp3.OkHttpClient.newSslSocketFactory(OkHttpClient.java:263)
    at okhttp3.OkHttpClient.<init>(OkHttpClient.java:229)
    at okhttp3.OkHttpClient$Builder.build(OkHttpClient.java:1015)
    at com.app.android.data.services.ApiClient.<init>(ApiClient.kt:56)
    at com.app.android.ui.splash.SplashPresenterImpl.checkUpdate(SplashPresenterImpl.kt:18)
    at com.app.android.ui.splash.SplashActivity.onCreate(SplashActivity.kt:40)
    at android.app.Activity.performCreate(Activity.java:5231)
    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1104)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2157)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2243)
    at android.app.ActivityThread.access$800(ActivityThread.java:135)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
    at android.os.Handler.dispatchMessage(Handler.java:102)
    at android.os.Looper.loop(Looper.java:136)
    at android.app.ActivityThread.main(ActivityThread.java:5019)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:515)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
    at dalvik.system.NativeStart.main(Native Method)
 Caused by: java.lang.IllegalStateException: Expected Android API level 21+ but was 19
    at okhttp3.internal.platform.AndroidPlatform.buildIfSupported(AndroidPlatform.java:238)
    at okhttp3.internal.platform.Platform.findPlatform(Platform.java:202)
    at okhttp3.internal.platform.Platform.<clinit>(Platform.java:79)

Gradle.Build 代码:

    apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'androidx.navigation.safeargs'
apply plugin: 'kotlin-kapt'
apply plugin: 'io.fabric'

android {
    compileSdkVersion 28
    defaultConfig {
        applicationId "com.app.android"
        minSdkVersion 16
        targetSdkVersion 28
        versionCode 100
        versionName "2.5.0"
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
        vectorDrawables.useSupportLibrary = true
        multiDexEnabled true
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    compileOptions {
        sourceCompatibility = '1.8'
        targetCompatibility = '1.8'
    }
}

repositories {
    maven { url 'https://maven.fabric.io/public' }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
    implementation 'androidx.appcompat:appcompat:1.1.0-beta01'
    implementation 'androidx.core:core-ktx:1.2.0-alpha02'
    implementation 'com.google.android.material:material:1.0.0'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    implementation 'androidx.recyclerview:recyclerview:1.0.0'
    implementation 'androidx.cardview:cardview:1.0.0'
    implementation 'androidx.viewpager:viewpager:1.0.0'
    implementation 'androidx.legacy:legacy-support-v4:1.0.0'
    implementation 'androidx.core:core:1.0.2'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test:runner:1.2.0'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
    //JWT decoder
    implementation 'com.auth0.android:jwtdecode:1.2.0'
    //Anko lib
    implementation "org.jetbrains.anko:anko-commons:0.10.8"
    implementation "org.jetbrains.anko:anko-design:0.10.8"
    //Rx
    implementation "io.reactivex.rxjava2:rxandroid:2.1.1"
    implementation "io.reactivex.rxjava2:rxjava:2.2.8"
    //OkHttp
    implementation 'com.squareup.okhttp3:okhttp:3.14.1'
    implementation "com.squareup.okhttp3:logging-interceptor:3.14.0"
    //Retrofit
    implementation "com.squareup.retrofit2:retrofit:2.5.0"
    implementation "com.squareup.retrofit2:adapter-rxjava2:2.5.0"
    implementation "com.squareup.retrofit2:converter-gson:2.5.0"
    //Gson
    implementation 'com.google.code.gson:gson:2.8.5'
    //Image
    implementation 'com.github.bumptech.glide:glide:4.9.0'
    annotationProcessor 'com.github.bumptech.glide:compiler:4.9.0'
    //Calligraphy
    implementation 'io.github.inflationx:calligraphy3:3.1.0'
    implementation 'io.github.inflationx:viewpump:1.0.0'
    //Navigation
    implementation 'androidx.navigation:navigation-fragment-ktx:2.1.0-alpha05'
    implementation 'androidx.navigation:navigation-ui-ktx:2.1.0-alpha05'
    //Preferences lib
    implementation 'com.github.MrNouri:GoodPrefs:1.0'
    //Multiple sizes
    implementation 'com.intuit.sdp:sdp-android:1.0.6'
    // OnBoarding
    implementation 'com.codemybrainsout.onboarding:onboarder:1.0.4'
    //Alerter
    implementation 'com.tapadoo.android:alerter:4.0.2'
    //Fabric answer
    implementation('com.crashlytics.sdk.android:answers:1.4.7@aar') { transitive = true }
    //Fabric crash
    implementation('com.crashlytics.sdk.android:crashlytics:2.9.9@aar') { transitive = true }
    //Adjust
    implementation 'com.adjust.sdk:adjust-android:4.17.0'
    implementation 'com.android.installreferrer:installreferrer:1.0'
    //Google and firebase services
    implementation 'com.google.android.gms:play-services-analytics:16.0.8'
    implementation 'com.google.firebase:firebase-core:16.0.9'
    implementation 'com.google.firebase:firebase-messaging:17.6.0'
    //Support MultiDex
    implementation 'androidx.multidex:multidex:2.0.1'
    //Room
    implementation 'androidx.room:room-runtime:2.1.0'
    annotationProcessor 'androidx.room:room-compiler:2.1.0'
    //Android svg and noneOldAndroid
    implementation 'com.caverock:androidsvg-aar:1.3'
    implementation 'com.nineoldandroids:library:2.4.0'
    //Animations
    implementation 'com.daimajia.easing:library:2.0@aar'
    implementation 'com.daimajia.androidanimations:library:2.3@aar'
}
apply plugin: 'com.google.gms.google-services'

我该如何解决?

【问题讨论】:

    标签: android kotlin retrofit2 okhttp3


    【解决方案1】:

    对于低于 21 的 minSDK,像这样在 gradle 中将 OkHttp 版本更改为 3.12.12 -

      //OkHttp
      implementation ("com.squareup.okhttp3:okhttp:3.12.12"){
          force = true //API 19 support
      }
      implementation 'com.squareup.okhttp3:logging-interceptor:3.12.12'
    

    它应该可以正常工作!

    【讨论】:

    • 抱歉,4.4。失败
    • 3.12.5 是 2019 年 9 月的最新版本
    • 您可以在这里找到最新的 3.12.x 版本:mvnrepository.com/artifact/com.squareup.okhttp3/okhttp
    • 新的 gradle 语法:implementation('com.squareup.okhttp3:okhttp') { version { strictly '3.12.12' } }
    • 我在更新 os 11 (Pixel 4) 后遇到同样的错误,有人测试过 android os 11 吗?我会尽力让你们知道
    【解决方案2】:

    OKHTTP 刚刚放弃了对 Android 4 的支持

    https://github.com/square/okhttp/issues/4481

    您必须为您的应用使用旧版本或单独的分支。

    有关更多信息,请参阅 Jessie Wilson 的这篇 Medium 帖子: https://medium.com/square-corner-blog/okhttp-3-13-requires-android-5-818bb78d07ce

    【讨论】:

    • 为我工作。欣赏链接以对决定充满信心。谢谢!
    【解决方案3】:

    对于仍然需要旧版 Android 库的所有人,您需要使用 OkHttp 3.12.x 分支。分支的最新版本是3.12.6。我已经测试并确认该版本适用于三星平板电脑 SM-T116NU (Android 19)。

    以下是 OkHttp 的摘录:

    OkHttp 3.12.x 分支支持 Android 2.3+(API 级别 9+)和 Java 7+。这些平台缺乏对 TLS 1.2 的支持,因此不应使用。但由于升级很困难,我们将在 2020 年 12 月 31 日之前将关键修复移植到 3.12.x 分支。

    【讨论】:

      【解决方案4】:

      根据Okhttp documentation,他们放弃了对 Android 4 的支持。

      解决方法是使用3.12.x版本的Okhttp:

      def okhttp_version="3.12.0"
      implementation "com.squareup.okhttp3:logging-interceptor:$okhttp_version"
      implementation("com.squareup.okhttp3:okhttp") {
          version { strictly "$okhttp_version" }
      }
      

      您还可以在Square blog 中阅读有关此更改的原因:

      为什么是 Android 5+,为什么是现在?

      TLS 是一种使 HTTPS 调用安全、私密和安全的机制。 认证。 OkHttp 知道五个版本:SSLv3 (1996)、TLSv1 (1999)、TLSv1.1 (2006)、TLSv1.2 (2008) 和 TLSv1.3 (2018)。我们掉了 2014 年支持 SSLv3 以应对 POODLE 攻击。

      现在是时候放弃 TLSv1 和 TLSv1.1 并让 TLSv1.2 成为 互联网的新最低标准。 10 月 15 日,我们的同事在 谷歌、Mozilla、微软和苹果宣布他们的浏览器 从 2020 年初开始将需要 TLSv1.2 或更高版本。

      Google 在 Android 5.0 中添加了对 TLSv1.2 的支持。甲骨文将其添加到 Java 8. 在 OkHttp 3.13 中,我们要求宿主平台内置 支持 TLSv1.2。

      Android 4.x 怎么样?

      Google 的分发信息中心显示,约 11% 的设备 2018 年 10 月访问 Play 商店时运行的是 Android 4.x。我们已经 创建了一个分支 OkHttp 3.12.x 来支持这些设备。我们应该吗 遇到任何严重的错误或安全问题,我们将支持 修复和发布。我们计划将这个分支维持到 12 月 2020 年 3 月 31 日。

      如果您真的需要 Android 4.x 上的 TLSv1.2,那是可能的!安库什 Gupta 编写了一份详尽的指南,解释了如何使用 Google 玩服务来做到这一点。即使您遵循此过程,您也应该 仍然在 Android 4.x 设备上使用 OkHttp 3.12.x。

      【讨论】:

        【解决方案5】:

        谢谢@https://stackoverflow.com/users/5773044/anupam 此代码适用于 Android API 19:

        // Note: 3.12.+ to support Android API 19
        implementation 'com.squareup.okhttp3:okhttp:3.12.10'
        implementation 'com.squareup.okhttp3:logging-interceptor:3.12.10'
        
        implementation 'io.reactivex.rxjava2:rxkotlin:2.4.0'
        implementation 'io.reactivex.rxjava2:rxandroid:2.1.1'
        
        implementation 'com.squareup.retrofit2:adapter-rxjava2:2.6.4'
        implementation 'com.squareup.retrofit2:converter-gson:2.6.4'
        implementation 'com.squareup.retrofit2:converter-scalars:2.6.4'
        testImplementation 'com.squareup.retrofit2:retrofit-mock:2.6.4'
        androidTestImplementation 'com.squareup.retrofit2:retrofit-mock:2.6.4'
        

        【讨论】:

        • 非常感谢,因为okhttp通常与改造一起使用,知道哪个改造版本适用于哪个okhttp版本是件好事
        【解决方案6】:

        @Anupam 答案的注意事项 - 如果您使用的是 Android Studio 4.0+,则不推荐使用 force

        https://docs.gradle.org/current/userguide/upgrading_version_5.html

        强制依赖 对一级依赖使用 force = true 强制依赖版本已被弃用。

        Force 存在语义和排序问题,可以通过使用严格的version constraint. 来避免

        未来的方法是使用关键字“strictly”进行依赖降级。 参考https://docs.gradle.org/current/userguide/dependency_downgrade_and_exclude.html#sec:enforcing_dependency_version

        所以你最终应该得到类似下面的东西......

          implementation ('com.squareup.okhttp3:okhttp'){ 
                    version {
                        strictly '3.12.12'
                    }
            }
        

        【讨论】:

          【解决方案7】:

          当我在 build.gradle 文件中添加以下内容时,我在 API 级别 19 中遇到了同样的问题。

          implementation 'com.squareup.okhttp3:okhttp:3.12.2'
          implementation 'com.squareup.okhttp3:logging-interceptor:3.13.1'
          

          最后,下面的代码帮助我解决了这个问题:

            implementation 'com.squareup.okhttp3:okhttp:3.11.0'
            implementation 'com.squareup.okhttp3:logging-interceptor:3.5.0'
          

          希望此解决方案适用于所有人。

          【讨论】:

            【解决方案8】:

            Android 4.4(适合我)

            def ok_http_version = "3.11.0"
            implementation "com.squareup.okhttp3:okhttp:$ok_http_version"
            implementation "com.squareup.okhttp3:logging-interceptor:$ok_http_version"
            

            【讨论】:

              【解决方案9】:

              Android 4.x?

              Google 的分发信息中心显示,在 2018 年 10 月访问 Play 商店的设备中,约有 11% 运行的是 Android 4.x。我们创建了一个分支 OkHttp 3.12.x 来支持这些设备。如果我们遇到任何严重的错误或安全问题,我们将支持修复并发布。我们计划将此分支维持到 2020 年 12 月 31 日。

              如果您真的需要 Android 4.x 上的 TLSv1.2,那是可能的! Ankush Gupta 编写了一份详尽的指南,解释了如何让 Google Play 服务来做这件事。即使您遵循此流程,您仍应在 Android 4.x 设备上使用 OkHttp 3.12.x。

              所以你可以使用下面的代码来解决你的问题

                implementation ("com.squareup.okhttp3:okhttp:3.12.12"){
                force = true //API 19 support
                }
                implementation 'com.squareup.okhttp3:logging-interceptor:3.12.12'
              

              【讨论】:

                【解决方案10】:

                21以下的api级别使用3.11.0版

                 implementation 'com.squareup.okhttp3:okhttp:3.11.0'
                 implementation 'com.squareup.okhttp3:logging-interceptor:3.11.0'
                

                【讨论】:

                  【解决方案11】:

                  在这里我解决了将依赖项降级到这个版本的问题

                  api 'com.squareup.retrofit2:retrofit:2.3.0'
                  api 'com.squareup.retrofit2:converter-gson:2.3.0'
                  api 'com.squareup.okhttp3:okhttp:3.8.0'
                  

                  并将此代码添加到 MainActivity 的 onCreate 中

                  try {
                        ProviderInstaller.installIfNeeded(this);
                      } catch (GooglePlayServicesRepairableException e) {
                        // Indicates that Google Play services is out of date, disabled, etc.
                        // Prompt the user to install/update/enable Google Play services.
                        GoogleApiAvailability.getInstance()
                          .showErrorNotification(this, e.getConnectionStatusCode());
                  
                      } catch (GooglePlayServicesNotAvailableException e) {
                        // Indicates a non-recoverable error; the ProviderInstaller is not able
                        // to install an up-to-date Provider.
                      }
                  

                  由于最新版本需要 android API 21 或更高版本,因此需要降级依赖项。

                  上面的代码用于更新您的安全提供程序以防止 SSL 漏洞。请参阅https://developer.android.com/training/articles/security-gms-provider.html 了解更多信息。

                  【讨论】:

                  猜你喜欢
                  • 2021-01-03
                  • 2020-02-28
                  • 2021-07-19
                  • 2021-06-01
                  • 2020-06-26
                  • 2015-04-16
                  • 1970-01-01
                  • 2014-10-03
                  • 1970-01-01
                  相关资源
                  最近更新 更多