如何修复Android的预期API级别为21+,但在Android中为19

Jak*_*ton 1 android kotlin retrofit2 okhttp3

在我的应用程序中,我想从服务器获取数据,为了连接到服务器,我使用了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)
    }
}
Run Code Online (Sandbox Code Playgroud)

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

我将此代码添加到gradle.build

compileOptions {
    sourceCompatibility = '1.8'
    targetCompatibility = '1.8'
}
Run Code Online (Sandbox Code Playgroud)

但再次向我显示错误!

错误信息 :

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)
Run Code Online (Sandbox Code Playgroud)

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'
Run Code Online (Sandbox Code Playgroud)

我该如何解决?

Zac*_*ary 15

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

  //OkHttp
    implementation 'com.squareup.okhttp3:okhttp:3.12.2'
    implementation "com.squareup.okhttp3:logging-interceptor:3.12.2"
Run Code Online (Sandbox Code Playgroud)

它应该工作正常!

  • 新的 gradle 语法:`implementation('com.squareup.okhttp3:okhttp') { version {严格'3.12.12' } }` (16认同)
  • 3.12.5的最新版本为2019年9月 (2认同)
  • 您可以在这里找到最新的 3.12.x 版本:https://mvnrepository.com/artifact/com.squareup.okhttp3/okhttp (2认同)

Kne*_*cht 8

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


ישו*_*ותך 7

对于仍然需要旧版 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 分支。


Ali*_*iSh 5

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

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

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

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

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

TLS 是使 HTTPS 调用安全、私密和经过身份验证的机制。OkHttp 知道五个版本:SSLv3 (1996)、TLSv1 (1999)、TLSv1.1 (2006)、TLSv1.2 (2008) 和 TLSv1.3 (2018)。为了应对 POODLE 攻击,我们在 2014 年放弃了对 SSLv3 的支持。

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

Google 在 Android 5.0 中添加了对 TLSv1.2 的支持。Oracle 在 Java 8 中添加了它。在 OkHttp 3.13 中,我们要求主机平台内置对 TLSv1.2 的支持。

安卓 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。