Android Error android.os.NetworkOnMainThreadException
Question
Request http in Android, the code is as follows, but there is an exception android.os.NetworkOnMainThreadException
.
public void retrieveFeed() {
OkHttpClient client = new OkHttpClient();
String url = "http://api.baidu.com/feed";
Request request = new Request.Builder()
.url(url)
.build();
try {
Response response = client.newCall(request).execute();
String result = response.body().string();
} catch (Exception e) {
e.printStackTrace();
}
}
W/System.err: android.os.NetworkOnMainThreadException
W/System.err: at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1303)
at java.net.Inet6AddressImpl.lookupHostByName(Inet6AddressImpl.java:86)
at java.net.Inet6AddressImpl.lookupAllHostAddr(Inet6AddressImpl.java:74)
at java.net.InetAddress.getAllByName(InetAddress.java:752)
at okhttp3.Dns$Companion$DnsSystem.lookup(Dns.kt:49)
W/System.err: 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:213)
at okhttp3.internal.connection.ExchangeFinder.findHealthyConnection(ExchangeFinder.kt:108)
at okhttp3.internal.connection.ExchangeFinder.find(ExchangeFinder.kt:76)
at okhttp3.internal.connection.RealCall.initExchange$okhttp(RealCall.kt:245)
at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.kt:32)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:100)
at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.kt:82)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:100)
at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.kt:83)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:100)
at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.kt:76)
W/System.err: at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:100)
at okhttp3.internal.connection.RealCall.getResponseWithInterceptorChain$okhttp(RealCall.kt:197)
at okhttp3.internal.connection.RealCall.execute(RealCall.kt:148)
at com.example.test.MainActivity.sendPolicy(MainActivity.java:47)
at java.lang.reflect.Method.invoke(Native Method)
at androidx.appcompat.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:397)
at android.view.View.performClick(View.java:5619)
at android.view.View$PerformClick.run(View.java:22298)
at android.os.Handler.handleCallback(Handler.java:754)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:163)
at android.app.ActivityThread.main(ActivityThread.java:6360)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:880)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:770)
Solution
There are two ways to solute this error.
1. Disable the strict mode
In the onCreate()
method of the Activity
, add the code as follow.
if (android.os.Build.VERSION.SDK_INT > 9) {
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
}
This is not recommended. We should not make network operations on main thread.
2. Use AsyncTask
class RetrieveFeedTask extends AsyncTask<String, Void, String> {
protected String doInBackground(String... urls) {
OkHttpClient client = new OkHttpClient();
String url = urls[0];
Request request = new Request.Builder()
.url(url)
.build();
Response response = null;
String result = "";
try {
response = client.newCall(request).execute();
result = response.body().string();
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
protected void onPostExecute(String result) {
Log.e("========", result);
}
}