Android UnknownHostException even there is an active and working internet connection
Asked Answered
P

1

6

I am having a lot of UnknownHostException thrown and the app is disconnected from the internet completely, this issue is happening in multiple apps I am working on the issue happens on Samsung and Xiaomi devices mainly

Affected Android Version

Devices Manufacture Version

this issue happens when the user leave the app in the background for a long time for example 12 hours and the user get access to the internet back only when the user restarts the app, I think these devices is clearing something form memory which is introducing this issue.

Non-fatal Exception: java.net.UnknownHostException: Unable to resolve host "ec2-157-175-229-147.me-south-1.compute.amazonaws.com": No address associated with hostname
       at java.net.Inet6AddressImpl.lookupHostByName(Inet6AddressImpl.java:124)
       at java.net.Inet6AddressImpl.lookupAllHostAddr(Inet6AddressImpl.java:103)
       at java.net.InetAddress.getAllByName(InetAddress.java:1152)
       at okhttp3.Dns$Companion$DnsSystem.lookup(Dns.kt:49)
       at okhttp3.internal.connection.RouteSelector.resetNextInetSocketAddress(RouteSelector.kt:164)
       at okhttp3.internal.connection.RouteSelector.nextProxy(RouteSelector.kt:129)
       at okhttp3.internal.connection.RouteSelector.next(RouteSelector.kt:71)
       at okhttp3.internal.connection.ExchangeFinder.findConnection(ExchangeFinder.kt:205)
       at okhttp3.internal.connection.ExchangeFinder.findHealthyConnection(ExchangeFinder.kt:106)
       at okhttp3.internal.connection.ExchangeFinder.find(ExchangeFinder.kt:74)
       at okhttp3.internal.connection.RealCall.initExchange$okhttp(RealCall.kt:255)
       at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.kt:32)
       at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
       at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.kt:95)
       at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
       at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.kt:83)
       at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
       at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.kt:76)
       at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
       at zerobranch.androidremotedebugger.logging.NetLoggingInterceptor.intercept(NetLoggingInterceptor.java:144)
       at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
       at com.pluto.plugins.network.PlutoInterceptor.intercept(PlutoInterceptor.kt:42)
       at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
       at okhttp3.logging.HttpLoggingInterceptor.intercept(HttpLoggingInterceptor.kt:221)
       at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
       at com.manexcard.manexpress.core.di.network_module.NetworkModule.provideAuthInterceptor$lambda-3(NetworkModule.kt:58)
       at com.manexcard.manexpress.core.di.network_module.NetworkModule.$r8$lambda$vr0s-sfISppz0jbkHEnesHFTcFo()
       at com.manexcard.manexpress.core.di.network_module.NetworkModule$$ExternalSyntheticLambda1.intercept()
       at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
       at okhttp3.internal.connection.RealCall.getResponseWithInterceptorChain$okhttp(RealCall.kt:201)
       at okhttp3.internal.connection.RealCall$AsyncCall.run(RealCall.kt:517)
       at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1137)
       at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:637)
       at java.lang.Thread.run(Thread.java:1012)

I am using Hilt to provide the dependencies and I am creating them as Singletons here is the dagger module:

@Module
@InstallIn(SingletonComponent::class)
object NetworkModule {

    @Singleton
    @Provides
    fun provideManexPressService(retrofit: Retrofit): ManexPressService =
        retrofit.create(ManexPressService::class.java)

    @Singleton
    @Provides
    fun provideGson(): Gson = Gson()

    @Provides   /* provide gson converter */
    fun provideConverterFactory(gson: Gson): Converter.Factory {
        return GsonConverterFactory.create(gson)
    }


    @Provides
    @Named("AuthInterceptor")
    fun provideAuthInterceptor(): Interceptor =
        Interceptor { chain ->
            val newBuilder = chain.request().newBuilder()
            if (chain.request().headers.none { it.first == "Authorization" }) {
                TokensManager.requestJwt?.let {
                    newBuilder.addHeader("Authorization", "Bearer $it")
                }
            }
            newBuilder.build().let { chain.proceed(it) }
        }

    @Provides
    fun providesNetLoggingInterceptor() = NetLoggingInterceptor()

    @Provides
    @Named("LoggingInterceptor")
    @Singleton
    fun httpLoggingInterceptor(): Interceptor {
        return if (BuildConfig.DEBUG)
            HttpLoggingInterceptor { message ->
                Timber.tag("OkHttp").d(message)
            }.setLevel(HttpLoggingInterceptor.Level.BODY)
        else
            return LiveOkhttpLoggingInterceptor { message ->
                Timber.tag("OkHttp").d(message)
            }.setLevel(HttpLoggingInterceptor.Level.BODY)
    }


    @Singleton
    @Provides
    fun client(
        @Named("AuthInterceptor")
        authInterceptor: Interceptor,
        @Named("LoggingInterceptor")
        loggingInterceptor: Interceptor,
        netLoggingInterceptor: NetLoggingInterceptor
    ): OkHttpClient = OkHttpClient().newBuilder().run {
        addInterceptor(authInterceptor)
        addInterceptor(loggingInterceptor)
        addInterceptor(PlutoInterceptor())
        addInterceptor(netLoggingInterceptor)
        connectTimeout(2, TimeUnit.MINUTES)
        readTimeout(2, TimeUnit.MINUTES)
        build()
    }


    /* operation work of api using retrofit */
    @Singleton
    @Provides
    fun provideRetrofit(
        @ApplicationContext context: Context,
        okHttpClient: OkHttpClient,
        converterFactory: Converter.Factory
    ): Retrofit = Retrofit.Builder()
        .baseUrl(context.getString(R.string.base_url))
        .addConverterFactory(converterFactory)
        .client(okHttpClient)
        .build()
}

I have researched a lot but I cannot find any valid solution I have implemented a workaround it seems to be working for now I have moved the network implementation to ActivityRetainedComponent and I am restarting the activity if it remains in the background for longer than 10 minutes. I know it is not the best practice but this is my only option for now I open for any suggestions.

Finally here are all my related dependencies:

    // Retrofit
    implementation 'com.squareup.retrofit2:retrofit:2.9.0'
    implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
    implementation 'com.squareup.okhttp3:okhttp:4.10.0'
    implementation 'com.squareup.okhttp3:logging-interceptor:4.9.2'

    // hilt implementation.
    implementation 'com.google.dagger:hilt-android:2.43.1'
    kapt 'com.google.dagger:hilt-android-compiler:2.43.1'
    kapt "androidx.hilt:hilt-compiler:1.0.0"
    implementation 'androidx.hilt:hilt-navigation-fragment:1.0.0'

Packard answered 19/9, 2022 at 14:8 Comment(5)
u have network security config set correctly?Encompass
Everything is working fine and I only get this on some devices if the app is left a long time in background, I think this is introduced if system initiated a proccess killPackard
If you want call an api when app is not in foreground then i would suggest to create a service with high priority and keep it in sync with the alarm manager This will make the api call and stop android from killing the process unless really necessary.Isoprene
@SwapnilPadaya for the comment however API calls are in the foreground of the appPackard
Android fix for this cs.android.com/android/_/android/platform/frameworks/base/+/…. I'm not sure if this goes into mainline modules, but I'm assuming not.Assurance
P
2

I have found a not-so-good workaround but working for now for me please if you found a better answer please do not hesitate to answer

  1. I have moved the networking library retrofit and OKHTTP to be @ActivityScoped
  2. Then added a timer to the application class to restart the activity when the activity is in stopped lifecycle state for more than 1 hour

this will make hilt refresh the networking libraries to fix the DNS issue I think that happen due to that system will free some memory from the app but still not sure the thing that I am sure of it work for now, I appreciate all inputs if anyone finds another solution

Packard answered 28/2, 2023 at 20:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.