我正在使用Retrofit的协程适配器,并且看到,如果由于URL错误而导致网络调用失败,则try/catch块将捕获它,但是如果我删除Internet权限以便获得SecurityException,则应用程序崩溃。
这是处理改造响应的代码:
override suspend fun execute(): Result<IpAddress> = try {
val result = dataRepository.getIpAddress().await()
Result.Success(result)
} catch (throwable: Throwable) {
if (throwable is JobCancellationException) {
throw throwable
}
Result.Error(throwable)
}
仓库很简单
override suspend fun getIpAddress(): Deferred<IpAddress> = dataService.getIpAddress()
和
interface DataService {
@GET("/?format=json")
fun getIpAddress(): Deferred<IpAddress>
}
为什么像UnknownHostException这样的异常会被捕获,但SecurityException会使应用程序崩溃?
这是崩溃日志
09-09 12:27:25.467 12465 12495 E AndroidRuntime: FATAL EXCEPTION: OkHttp Dispatcher
09-09 12:27:25.467 12465 12495 E AndroidRuntime: Process: com.example.coroutines, PID: 12465
09-09 12:27:25.467 12465 12495 E AndroidRuntime: java.lang.SecurityException: Permission denied (missing INTERNET permission?)
09-09 12:27:25.467 12465 12495 E AndroidRuntime: at java.net.Inet6AddressImpl.lookupHostByName(Inet6AddressImpl.java:151)
09-09 12:27:25.467 12465 12495 E AndroidRuntime: at java.net.Inet6AddressImpl.lookupAllHostAddr(Inet6AddressImpl.java:105)
09-09 12:27:25.467 12465 12495 E AndroidRuntime: at java.net.InetAddress.getAllByName(InetAddress.java:1154)
09-09 12:27:25.467 12465 12495 E AndroidRuntime: at okhttp3.Dns$1.lookup(Dns.java:40)
09-09 12:27:25.467 12465 12495 E AndroidRuntime: at okhttp3.internal.connection.RouteSelector.resetNextInetSocketAddress(RouteSelector.java:185)
09-09 12:27:25.467 12465 12495 E AndroidRuntime: at okhttp3.internal.connection.RouteSelector.nextProxy(RouteSelector.java:149)
09-09 12:27:25.467 12465 12495 E AndroidRuntime: at okhttp3.internal.connection.RouteSelector.next(RouteSelector.java:84)
09-09 12:27:25.467 12465 12495 E AndroidRuntime: at okhttp3.internal.connection.StreamAllocation.findConnection(StreamAllocation.java:214)
09-09 12:27:25.467 12465 12495 E AndroidRuntime: at okhttp3.internal.connection.StreamAllocation.findHealthyConnection(StreamAllocation.java:135)
09-09 12:27:25.467 12465 12495 E AndroidRuntime: at okhttp3.internal.connection.StreamAllocation.newStream(StreamAllocation.java:114)
09-09 12:27:25.467 12465 12495 E AndroidRuntime: at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.java:42)
09-09 12:27:25.467 12465 12495 E AndroidRuntime: at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
09-09 12:27:25.467 12465 12495 E AndroidRuntime: at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
09-09 12:27:25.467 12465 12495 E AndroidRuntime: at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.java:93)
09-09 12:27:25.467 12465 12495 E AndroidRuntime: at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
09-09 12:27:25.467 12465 12495 E AndroidRuntime: at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
09-09 12:27:25.467 12465 12495 E AndroidRuntime: at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.java:93)
09-09 12:27:25.467 12465 12495 E AndroidRuntime: at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
09-09 12:27:25.467 12465 12495 E AndroidRuntime: at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:126)
09-09 12:27:25.467 12465 12495 E AndroidRuntime: at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
09-09 12:27:25.467 12465 12495 E AndroidRuntime: at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
09-09 12:27:25.467 12465 12495 E AndroidRuntime: at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:200)
09-09 12:27:25.467 12465 12495 E AndroidRuntime: at okhttp3.RealCall$AsyncCall.execute(RealCall.java:147)
09-09 12:27:25.467 12465 12495 E AndroidRuntime: at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
09-09 12:27:25.467 12465 12495 E AndroidRuntime: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
09-09 12:27:25.467 12465 12495 E AndroidRuntime: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
09-09 12:27:25.467 12465 12495 E AndroidRuntime: at java.lang.Thread.run(Thread.java:764)
09-09 12:27:25.467 12465 12495 E AndroidRuntime: Caused by: android.system.GaiException: android_getaddrinfo failed: EAI_NODATA (No address associated with hostname)
09-09 12:27:25.467 12465 12495 E AndroidRuntime: at libcore.io.Linux.android_getaddrinfo(Native Method)
09-09 12:27:25.467 12465 12495 E AndroidRuntime: at libcore.io.BlockGuardOs.android_getaddrinfo(BlockGuardOs.java:172)
09-09 12:27:25.467 12465 12495 E AndroidRuntime: at java.net.Inet6AddressImpl.lookupHostByName(Inet6AddressImpl.java:137)
09-09 12:27:25.467 12465 12495 E AndroidRuntime: ... 26 more
09-09 12:27:25.467 12465 12495 E AndroidRuntime: Caused by: android.system.ErrnoException: android_getaddrinfo failed: EACCES (Permission denied)
09-09 12:27:25.467 12465 12495 E AndroidRuntime: ... 29 more
最佳答案
因为在某些情况下,Retrofit会在内部捕获它并将其作为错误传递回去,因此您可能会希望处理它。在另一种情况下,它无法捕获该应用程序并使它崩溃。没有什么办法可以改变这种在其内部线程上发生的 fork 翻新的过程,仅保留互联网的许可就可以了。