Okhttp Library - Networkonmainthreadexception on Simple Post

OkHttp Library - NetworkOnMainThreadException on simple post

You should use OkHttp's async method.

public static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");

OkHttpClient client = new OkHttpClient();

Call post(String url, String json, Callback callback) {
RequestBody body = RequestBody.create(JSON, json);
Request request = new Request.Builder()
.url(url)
.post(body)
.build();
Call call = client.newCall(request);
call.enqueue(callback);
return call;
}

And then your response would be handled in the callback (OkHttp 2.x):

post("http://www.roundsapp.com/post", json, new Callback() {
@Override
public void onFailure(Request request, Throwable throwable) {
// Something went wrong
}

@Override public void onResponse(Response response) throws IOException {
if (response.isSuccessful()) {
String responseStr = response.body().string();
// Do what you want to do with the response.
} else {
// Request not successful
}
}
});

Or OkHttp 3.x/4.x:

post("http://www.roundsapp.com/post", "", new Callback() {
@Override
public void onFailure(Call call, IOException e) {
// Something went wrong
}

@Override
public void onResponse(Call call, Response response) throws IOException {
if (response.isSuccessful()) {
String responseStr = response.body().string();
// Do what you want to do with the response.
} else {
// Request not successful
}
}
});

Take a look at their recipes for more examples: http://square.github.io/okhttp/recipes/

NetworkOnMainThreadException using OkHttp with RxJava2

You're calling service.getData(httpParamObject) in the main thread and passing that result to Observable.just. So your subscribeOn has no effect.

Check the documentation of Observable.create and use it instead of Observable.just

okhttp3 throws NetworkOnMainThreadException when loading images asynchronously with glide

My approach was totally wrong. I thought that BaseGlideUrlLoader runs on a background-thread, but it doesn't.

So the code to go is the following:

@Override
public void onBindViewHolder(Presenter.ViewHolder viewHolder, Object item) {

final ImageCardView cardView = (ImageCardView) viewHolder.view;

OkHttpClient client = new OkHttpClient;
Request request = new Request.Builder().url(image_url).build();

client.newCall(request).enqueue(new Callback() {
@Override public void onFailure(Call call, IOException e) {
e.printStackTrace();
}

@Override public void onResponse(Call call, Response response) throws IOException {
try (ResponseBody responseBody = response.body()) {
if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);

String imageFromResponse = responseBody.string();
// do whatever is needed to get the image (i.e JSON-handling)

Handler mainHandler = new Handler(Looper.getMainLooper());
Runnable myRunnable = new Runnable() {
@Override
public void run() {
Glide.with(cardView.getContext())
.load(imagefromResponse)
.error(mDefaultCardImage)
.into(cardView.getMainImageView());
}
};
}
});

}

KHTTP android.os.NetworkOnMainThreadException on POST request

Even though the exception message is very clear, If you want to understand in detail why this happens, please read

As to how you can fix this, you can use kotln coroutines for this, once you have included the given dependencies in your build, you can do the following

// Start network request on a background thread using coroutine
lifecycleScope.launch(Dispatchers.IO) {
khttp.post(
"http://127.0.0.1:5000/order",
headers = mapOf(
"address" to address.toString(),
"items" to Json.encodeToString(listOf("Su x1", "Gofret x5", "Dondurma x1")),
"price" to "100",
"orderer" to name.toString(),
"phone" to phone.toString()
),
)
}

How to resolve android.os.NetworkOnMainThreadException?

The Android OS does not allow heavy process to execute in the main thread/UI Thread because the application will slow down, decreasing performance and the application will lag.

However, you can execute it in an AsyncTask as shown here. Do your process/call your function in the doInBackground of this asyncTask.

private class Download extends AsyncTask<String, Void, String> {
ProgressDialog pDialog;

@Override
protected void onPreExecute() {
super.onPreExecute();
Log.d("Hi", "Download Commencing");

pDialog = new ProgressDialog(MainActivity.this);
pDialog.setMessage("Downloading Database...");

String message= "Executing Process";

SpannableString ss2 = new SpannableString(message);
ss2.setSpan(new RelativeSizeSpan(2f), 0, ss2.length(), 0);
ss2.setSpan(new ForegroundColorSpan(Color.BLACK), 0, ss2.length(), 0);

pDialog.setMessage(ss2);

pDialog.setCancelable(false);
pDialog.show();
}

@Override
protected String doInBackground(String... params) {

//INSERT YOUR FUNCTION CALL HERE

return "Executed!";

}

@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
Log.d("Hi", "Done Downloading.");
pDialog.dismiss();

}
}

and call it as such: new Download().execute(""); from another function.

You can do away with the Progress Dialog. I personally like it because I know my process will finish (like data loading) before the user can do anything, ensuring that no error occurs when the user interacts with the program.

How can I fix 'android.os.NetworkOnMainThreadException'?

NOTE : AsyncTask was deprecated in API level 30.

AsyncTask | Android Developers

This exception is thrown when an application attempts to perform a networking operation on its main thread. Run your code in AsyncTask:

class RetrieveFeedTask extends AsyncTask<String, Void, RSSFeed> {

private Exception exception;

protected RSSFeed doInBackground(String... urls) {
try {
URL url = new URL(urls[0]);
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser parser = factory.newSAXParser();
XMLReader xmlreader = parser.getXMLReader();
RssHandler theRSSHandler = new RssHandler();
xmlreader.setContentHandler(theRSSHandler);
InputSource is = new InputSource(url.openStream());
xmlreader.parse(is);

return theRSSHandler.getFeed();
} catch (Exception e) {
this.exception = e;

return null;
} finally {
is.close();
}
}

protected void onPostExecute(RSSFeed feed) {
// TODO: check this.exception
// TODO: do something with the feed
}
}

How to execute the task:

In MainActivity.java file you can add this line within your oncreate() method

new RetrieveFeedTask().execute(urlToRssFeed);

Don't forget to add this to AndroidManifest.xml file:

<uses-permission android:name="android.permission.INTERNET"/>

NetworkOnMainThreadException

I have tested this and it does in fact happen on the emulator as well. Better make sure you test your app at least on the emulator if you plan to get it onto the 3.0 tablets and beyond.

When parse a JSON response using Okhttp and GSON Library then i am getting Network on main thread exception

Use enqueue() instead of execute().

Execute runs it on the same thread (which in this case is the UI thread).

Enqueue runs it on a background thread.

You want to call networking operations on a background thread, and NOT on the UI thread.

See the Call interface here.



Related Topics



Leave a reply



Submit