一、簡(jiǎn)介
自己在做項(xiàng)目的時(shí)候,發(fā)現(xiàn)APK在某廠家的一款機(jī)頂盒上開(kāi)機(jī)啟動(dòng)的時(shí)候,接收開(kāi)機(jī)廣播拉起進(jìn)程之后,進(jìn)程突然崩潰,如果再次拉起進(jìn)程,又能夠正常使用了,經(jīng)過(guò)全局異常捕獲發(fā)現(xiàn),導(dǎo)致進(jìn)程崩潰的原因居然是okhttp中拋出的一個(gè)異常:
java.lang.SecurityException Permission denied (missing INTERNET permission?)
at java.net.InetAddress.lookupHostByName(InetAddress.java 418)
at java.net.InetAddress.getAllByNameImpl(InetAddress.java 236)
at java.net.InetAddress.getAllByName(InetAddress.java 214)
at okhttp3.Dns$1.lookup(Dns.java 39)
at okhttp3.internal.connection.RouteSelector.resetNextInetSocketAddress(RouteSelector.java 170)
at okhttp3.internal.connection.RouteSelector.nextProxy(RouteSelector.java 136)
at okhttp3.internal.connection.RouteSelector.next(RouteSelector.java 81)
...
第一眼看這個(gè)異常,肯定會(huì)想到,這特么的是沒(méi)有加權(quán)限?。。?!然而事情如果有這么簡(jiǎn)單的話,還填個(gè)毛的坑?。。?!接下來(lái),講一下關(guān)于這個(gè)異常的情況。
二、異常原因分析
原因一:AndroidMinifest.xml中未添加網(wǎng)絡(luò)權(quán)限
對(duì)于這種異常,大部分情況下確實(shí)因?yàn)闆](méi)有添加網(wǎng)絡(luò)權(quán)限導(dǎo)致的,一般只需要添加
<uses-permission android:name="android.permission.INTERNET" />
該權(quán)限即可解決該異常引起的崩潰,然后我再項(xiàng)目中查了一遍又一遍,確認(rèn)了一次又一次,確定不是由于未添加網(wǎng)絡(luò)權(quán)限導(dǎo)致的該異常,難道還有其他原因?
原因二:AndroidMinifest.xml中未添加網(wǎng)絡(luò)狀態(tài)權(quán)限
查看了出現(xiàn)該異常的其他博客,也有人在出現(xiàn)該異常時(shí)添加如下權(quán)限就解決了的
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
事實(shí)上,依然沒(méi)有效果,開(kāi)機(jī)該崩潰還得崩潰;后來(lái)在想干脆將網(wǎng)絡(luò)權(quán)限都加上,流氓點(diǎn)就流氓點(diǎn),但該總不會(huì)導(dǎo)致這個(gè)異常了吧?
爽不過(guò)三秒,開(kāi)啟重啟,還是崩潰了~~~~~~~
三、解決問(wèn)題
因?yàn)樽龃笃翍?yīng)用開(kāi)發(fā),很多應(yīng)用需要在開(kāi)機(jī)之后就要后臺(tái)運(yùn)行,如果開(kāi)機(jī)進(jìn)程掛了不能起來(lái)就玩完了。查了很多資料,目前尚不明確具體什么原因?qū)е碌脑摦惓?,初步定位為與ROM有關(guān),但事情總得想法子解決的。如何解決?
既然是okHttp網(wǎng)絡(luò)訪問(wèn)出現(xiàn)的異常導(dǎo)致的崩潰,那么我這邊想法是通過(guò)okHttp攔截器來(lái)攔截該異常,并做相關(guān)處理。具體的攔截器寫(xiě)法如下:
public class InternetPermissionExceptionInterceptor implements Interceptor {
private static final String PERMISSION_EXCEPTION = "Permission denied (missing INTERNET permission?)";
@Override
public Response intercept(Chain chain) throws IOException {
try {
return chain.proceed(chain.request());
} catch (Throwable e) {
if (PERMISSION_EXCEPTION.equals(e.getMessage()) || e instanceof SecurityException) {
//此處,根據(jù)自己的業(yè)務(wù)需求來(lái)決定如何處理攔截到的該異常
AlarmTimer.setAlarmTimer(
XMContext.AppContext(),
System.currentTimeMillis() + 1000 * 10,
AlarmTimer.TIMER_ACTION,
BootBroadcastReceiver.class);
System.exit(0);
}
if (e instanceof IOException) {
throw e;
} else {
throw new IOException(e);
}
}
}
}
此處,因?yàn)槲覀兊捻?xiàng)目一下幾個(gè)要點(diǎn):
1、必須保證開(kāi)機(jī)能夠正常啟動(dòng)
2、有專門(mén)的崩潰收集平臺(tái)
所以我這里就是先搞一個(gè)定時(shí)器,10秒后定時(shí)發(fā)送廣播,拉起自己,同時(shí)手動(dòng)kill掉進(jìn)程,這樣既保證了崩潰平臺(tái)不會(huì)大批量收集該異常,同時(shí)進(jìn)程保證也能夠正常再開(kāi)機(jī)的時(shí)候運(yùn)行,雖然kill了一次,但不影響業(yè)務(wù),至此,雖然沒(méi)找到具體的原因,但還是解決了該問(wèn)題。
四、寫(xiě)在最后
如果有哪位在使用oKhttop的時(shí)候也出現(xiàn)了這類異常,并且不是由于簡(jiǎn)單的權(quán)限問(wèn)題導(dǎo)致的,分析到了原因還望告知,謝謝。
同步發(fā)布于掘金:https://juejin.im/post/5b129d295188257d86687532