okHttpClient發起網路請求失敗
阿新 • • 發佈:2020-10-21
Android中傳送HTTP請求,報錯如下
E/AndroidRuntime: FATAL EXCEPTION: main Process: cn.iyikong.managementterminal, PID: 4447 android.os.NetworkOnMainThreadException at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1571) at java.net.Inet6AddressImpl.lookupHostByName(Inet6AddressImpl.java:115) at java.net.Inet6AddressImpl.lookupAllHostAddr(Inet6AddressImpl.java:103) at java.net.InetAddress.getAllByName(InetAddress.java:1152) at okhttp3.Dns$Companion$SYSTEM$1.lookup(Dns.kt:48) at okhttp3.internal.connection.RouteSelector.resetNextInetSocketAddress(RouteSelector.kt:160) at okhttp3.internal.connection.RouteSelector.nextProxy(RouteSelector.kt:125) at okhttp3.internal.connection.RouteSelector.next(RouteSelector.kt:71) at okhttp3.internal.connection.ExchangeFinder.findConnection(ExchangeFinder.kt:199) at okhttp3.internal.connection.ExchangeFinder.findHealthyConnection(ExchangeFinder.kt:109) at okhttp3.internal.connection.ExchangeFinder.find(ExchangeFinder.kt:77) at okhttp3.internal.connection.Transmitter.newExchange$okhttp(Transmitter.kt:162) at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.kt:35) at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:112) at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:87) at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.kt:82) at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:112) at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:87) at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.kt:84) at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:112) at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.kt:71) at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:112) at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:87) at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.kt:184) at okhttp3.RealCall.execute(RealCall.kt:66) at cn.iyikong.managementterminal.service.WebService.getPullAndPushNumber(WebService.java:606) at cn.iyikong.managementterminal.VideoActivity.onMediaOnPreparedNotify(VideoActivity.java:1213) at cn.iyikong.managementterminal.handler.MediaHandler.handleMessage(MediaHandler.java:48) at android.os.Handler.dispatchMessage(Handler.java:107) at android.os.Looper.loop(Looper.java:224) at android.app.ActivityThread.main(ActivityThread.java:7562) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:539) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:950) E/CrashReport: Java Crash Happen cause by main(2)
在Activity.java中呼叫HTTP網路請求時,怎麼都走不過去
/** * 獲取視訊拉流數量 * @author ct * @return String */ public static Integer getPullAndPushNumber(String imei) { Integer pullNumber = 0; OkHttpClient okHttpClient = new OkHttpClient(); Request request = new Request.Builder() .url(Constant.GET_EQUIP_PULL_Number) .build(); try (Response response = okHttpClient.newCall(request).execute()) { //每次到這裡都會報錯 if(null != response.body()){ //1.獲取請求資料轉換成map集合 Map map = JSON.parseObject(response.body().string(),Map.class); //2.獲得詳細列表物件集合轉換成map集合 Map map2 = JSON.parseObject(map.get("bridges").toString()); //3.map迴圈key值 for (Object obj : map2.keySet()){ //4.當key值與IMEI相等時,獲取拉流裝置數量 if(obj.equals(imei)){ //5.拉流裝置數量等於陣列字串中逗號的數量 pullNumber = map2.get(obj).toString().split(",").length; } } } } catch (IOException e){ e.printStackTrace(); } return pullNumber; }
翻了翻資料,發現原因是:不允許在主執行緒中進行網路訪問
下面是我找到的幾種解決方法,我用的第一個
一、直接在請求的Activity中的onCreate方法中新增如下程式碼:
Activity.java
StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder() .detectDiskReads().detectDiskWrites().detectNetwork() .penaltyLog().build()); StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder() .detectLeakedSqlLiteObjects().detectLeakedClosableObjects() .penaltyLog().penaltyDeath().build());
發起請求
/**
* 獲取視訊拉流數量
* @author ct
* @return Integer
*/
public static Integer getPullAndPushNumber(String imei) {
Integer pullNumber = 0;
OkHttpClient okHttpClient = new OkHttpClient();
Request request = new Request.Builder()
.url(Constant.GET_EQUIP_PULL_Number)
.build();
try (Response response = okHttpClient.newCall(request).execute()) {
if(null != response.body()){
//1.獲取請求資料轉換成map集合
Map map = JSON.parseObject(response.body().string(),Map.class);
//2.獲得詳細列表物件集合轉換成map集合
Map map2 = JSON.parseObject(map.get("bridges").toString());
//3.map迴圈key值
for (Object obj : map2.keySet()){
//4.當key值與IMEI相等時,獲取拉流裝置數量
if(obj.equals(imei)){
//5.拉流裝置數量等於陣列字串中逗號的數量
pullNumber = map2.get(obj).toString().split(",").length;
}
}
}
} catch (IOException e){
e.printStackTrace();
}
return pullNumber;
}
二、建立子執行緒,把網路請求放到子執行緒裡執行,這種沒試過,這種好像沒有返回值,麼法把查到的資料顯示在頁面上,不太懂
new Thread(){
@Override
public void run()
{
//把網路訪問的程式碼放在這裡
}
}.start();
三、使用非同步請求
/**
* 獲取視訊拉流數量
* @author ct
* @return Integer
*/
public static Integer getPullAndPushNumber(String imei) {
OkHttpClient okHttpClient = new OkHttpClient();
HttpUrl.Builder urlBuilder = HttpUrl.parse(Constant.GET_EQUIP_PULL_Number)
.newBuilder();
Request request = new Request.Builder()
.url(urlBuilder.build())
.build();
Call call = okHttpClient.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
LogUtil.d("getPullAndPushNumber", "onFailure: ");
}
@Override
public void onResponse(Call call, Response response) throws IOException {
//1.字串轉JSON物件
Map map = JSON.parseObject(response.body().string(),Map.class);
//4.獲取詳細引數字串
for (Object obj : map.keySet()){
LogUtil.d("getPullAndPushNumber", "key為:"+obj+"值為:"+map.get(obj));
}
Map map2 = JSON.parseObject(map.get("bridges").toString());
for (Object obj : map2.keySet()){
LogUtil.d("getPullAndPushNumber-----2", "key為:"+obj+"值為:"+map2.get(obj));
if(obj.equals(imei)){
System.out.println(map2.get(obj).toString().split(",").length);
}
}
}
});
return 0;
}
總結:
用了第一個與第三個方法,問題解決了;至於為啥解決了就不太明白了,大概是主執行緒中不允許使用網路請求
第三個方法沒有返回值,適合進行增刪改操作,查詢的話還是用第一個吧,以後再學學還有沒有其他方法